Browse Source

Fixed some code completion bugs.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@208 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 21 years ago
parent
commit
325d2690ec
  1. 20
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/ExpressionFinder.cs
  2. 13
      src/AddIns/Misc/NUnitPad/Project/Src/Gui/NUnitPadContent.cs
  3. 45
      src/AddIns/Misc/NUnitPad/Project/Src/Gui/TestTreeView.cs
  4. 5
      src/Main/Base/Project/Src/Dom/IClass.cs
  5. 51
      src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs
  6. 61
      src/Main/Base/Project/Src/Dom/Implementations/DefaultUsing.cs
  7. 30
      src/Main/Base/Project/Src/Dom/LanguageProperties.cs
  8. 377
      src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs
  9. 7
      src/Main/Base/Project/Src/Services/ParserService/IProjectContent.cs
  10. 15
      src/Main/Base/Test/NRefactoryResolverTests.cs
  11. 73
      src/Main/Base/Test/SearchClassTests.cs

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

@ -255,6 +255,11 @@ namespace CSharpBinding.Parser
goto default; goto default;
} }
break; break;
case '#':
if (!ReadToEOL(text, ref curOffset, ref offset)) {
return null;
}
break;
default: default:
outText.Append(ch); outText.Append(ch);
++curOffset; ++curOffset;
@ -279,6 +284,8 @@ namespace CSharpBinding.Parser
bool ReadChar(StringBuilder outText, string text, ref int curOffset) bool ReadChar(StringBuilder outText, string text, ref int curOffset)
{ {
if (curOffset > initialOffset)
return false;
char first = text[curOffset++]; char first = text[curOffset++];
outText.Append(first); outText.Append(first);
if (curOffset > initialOffset) if (curOffset > initialOffset)
@ -447,7 +454,7 @@ namespace CSharpBinding.Parser
break; break;
default: default:
if (IsDigit()) { if (IsDigit()) {
string digit = ReadDigit(ch); ReadDigit(ch);
curTokenType = Digit; curTokenType = Digit;
} else if (IsIdentifierPart(ch)) { } else if (IsIdentifierPart(ch)) {
string ident = ReadIdentifier(ch); string ident = ReadIdentifier(ch);
@ -577,18 +584,19 @@ namespace CSharpBinding.Parser
return identifier; return identifier;
} }
string ReadDigit(char ch) void ReadDigit(char ch)
{ {
string digit = ch.ToString(); //string digit = ch.ToString();
while (Char.IsDigit(Peek()) || Peek() == '.') { while (Char.IsDigit(Peek()) || Peek() == '.') {
digit = GetNext() + digit; GetNext();
//digit = GetNext() + digit;
} }
return digit; //return digit;
} }
bool IsIdentifierPart(char ch) bool IsIdentifierPart(char ch)
{ {
return Char.IsLetterOrDigit(ch) || ch == '_'; return Char.IsLetterOrDigit(ch) || ch == '_' || ch == '@';
} }
#endregion #endregion

13
src/AddIns/Misc/NUnitPad/Project/Src/Gui/NUnitPadContent.cs

@ -127,7 +127,7 @@ namespace ICSharpCode.NUnitPad
void ProjectServiceEndBuild(object sender, EventArgs e) void ProjectServiceEndBuild(object sender, EventArgs e)
{ {
if (autoLoadItems) { if (autoLoadItems) {
testTreeView.Invoke(new ThreadStart(RefreshProjectAssemblies)); RefreshProjectAssemblies();
} }
} }
@ -159,9 +159,7 @@ namespace ICSharpCode.NUnitPad
void ProjectServiceCombineClosed(object sender, EventArgs e) void ProjectServiceCombineClosed(object sender, EventArgs e)
{ {
if (testDomains.Count > 0) { UnloadAppDomains();
UnloadAppDomains();
}
} }
void UnloadAppDomains() void UnloadAppDomains()
@ -177,10 +175,13 @@ namespace ICSharpCode.NUnitPad
public void RunTests() public void RunTests()
{ {
if (ProjectService.OpenSolution == null) return;
if (!autoLoadItems) { if (!autoLoadItems) {
autoLoadItems = true; autoLoadItems = true;
RefreshProjectAssemblies(); RefreshProjectAssemblies();
} }
testTreeView.RunTests(); testTreeView.RunTests();
} }
@ -188,13 +189,15 @@ namespace ICSharpCode.NUnitPad
{ {
UnloadAppDomains(); UnloadAppDomains();
if (ProjectService.OpenSolution == null) return;
foreach (IProject project in ProjectService.OpenSolution.Projects) { foreach (IProject project in ProjectService.OpenSolution.Projects) {
string outputAssembly = project.OutputAssemblyFullPath; string outputAssembly = project.OutputAssemblyFullPath;
try { try {
TestSuiteBuilder builder = new TestSuiteBuilder(); TestSuiteBuilder builder = new TestSuiteBuilder();
Console.WriteLine("Try : " + outputAssembly); Console.WriteLine("Try : " + outputAssembly);
Test testDomain = builder.Build(outputAssembly); Test testDomain = builder.Build(outputAssembly);
testTreeView.PrintTests(outputAssembly, testDomain); testTreeView.PrintTests(outputAssembly, testDomain, project);
} catch (Exception e) { } catch (Exception e) {
testTreeView.PrintTestErrors(outputAssembly, e); testTreeView.PrintTestErrors(outputAssembly, e);
} }

45
src/AddIns/Misc/NUnitPad/Project/Src/Gui/TestTreeView.cs

@ -12,6 +12,7 @@ using System.Windows.Forms;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using NUnit.Core; using NUnit.Core;
using NUnit.Framework; using NUnit.Framework;
@ -32,6 +33,22 @@ namespace ICSharpCode.NUnitPad
TestItemSelected = 2, TestItemSelected = 2,
} }
sealed class TestItemTag {
public readonly ITest Test;
public readonly IProject Project;
public TestItemTag(ITest test, IProject project) {
this.Test = test;
this.Project = project;
}
public void Run(EventListener listener) {
if (Test is Test)
(Test as Test).Run(listener);
}
public Position GetPosition() {
return ParserService.GetProjectContent(Project).GetPosition(Test.FullName.Replace('+', '.'));
}
}
protected TestTreeViewState internalState = TestTreeViewState.Nothing; protected TestTreeViewState internalState = TestTreeViewState.Nothing;
public System.Enum InternalState { public System.Enum InternalState {
@ -50,10 +67,10 @@ namespace ICSharpCode.NUnitPad
if (treeView.SelectedNode == null) { if (treeView.SelectedNode == null) {
return false; return false;
} }
ITest test = treeView.SelectedNode.Tag as ITest; TestItemTag test = treeView.SelectedNode.Tag as TestItemTag;
if (test != null) { if (test != null) {
Position position = ParserService.CurrentProjectContent.GetPosition(test.FullName.Replace('+', '.')); Position position = test.GetPosition();
return position != null && position.Cu != null; return position != null && position.Cu != null;
} }
return false; return false;
@ -65,7 +82,7 @@ namespace ICSharpCode.NUnitPad
if (treeView.SelectedNode == null) { if (treeView.SelectedNode == null) {
return false; return false;
} }
ITest test = treeView.SelectedNode.Tag as ITest; TestItemTag test = treeView.SelectedNode.Tag as TestItemTag;
return test != null; return test != null;
} }
} }
@ -144,26 +161,26 @@ namespace ICSharpCode.NUnitPad
treeView.Nodes.Add(assemblyNode); treeView.Nodes.Add(assemblyNode);
} }
public void PrintTests(string assembly, Test test) public void PrintTests(string assembly, Test test, IProject project)
{ {
TreeNode assemblyNode = new TreeNode(Path.GetFileName(assembly)); TreeNode assemblyNode = new TreeNode(Path.GetFileName(assembly));
assemblyNode.Tag = test; assemblyNode.Tag = new TestItemTag(test, project);
treeView.Nodes.Add(assemblyNode); treeView.Nodes.Add(assemblyNode);
if (test != null) { if (test != null) {
AddTests(assemblyNode, test); AddTests(assemblyNode, test, project);
} }
assemblyNode.Expand(); assemblyNode.Expand();
} }
public void AddTests(TreeNode node, ITest test) public void AddTests(TreeNode node, ITest test, IProject project)
{ {
foreach (ITest childTest in test.Tests) { foreach (ITest childTest in test.Tests) {
TreeNode newNode = new TreeNode(childTest.Name); TreeNode newNode = new TreeNode(childTest.Name);
treeNodeHash[childTest.UniqueName] = newNode; treeNodeHash[childTest.UniqueName] = newNode;
newNode.ImageIndex = newNode.SelectedImageIndex = 0; newNode.ImageIndex = newNode.SelectedImageIndex = 0;
newNode.Tag = childTest; newNode.Tag = new TestItemTag(childTest, project);
if (childTest.IsSuite) { if (childTest.IsSuite) {
AddTests(newNode, childTest); AddTests(newNode, childTest, project);
node.Expand(); node.Expand();
} }
node.Nodes.Add(newNode); node.Nodes.Add(newNode);
@ -173,10 +190,10 @@ namespace ICSharpCode.NUnitPad
public void GotoDefinition() public void GotoDefinition()
{ {
if (treeView.SelectedNode != null) { if (treeView.SelectedNode != null) {
ITest test = treeView.SelectedNode.Tag as ITest; TestItemTag testTag = treeView.SelectedNode.Tag as TestItemTag;
if (test != null) { if (testTag != null) {
Position position = ParserService.CurrentProjectContent.GetPosition(test.FullName.Replace('+', '.')); Position position = testTag.GetPosition();
if (position != null && position.Cu != null) { if (position != null && position.Cu != null) {
@ -203,7 +220,7 @@ namespace ICSharpCode.NUnitPad
TreeNode selectedNode = treeView.SelectedNode; TreeNode selectedNode = treeView.SelectedNode;
if (selectedNode != null) { if (selectedNode != null) {
Test test = selectedNode.Tag as Test; TestItemTag test = selectedNode.Tag as TestItemTag;
if (test != null) { if (test != null) {
test.Run(this); test.Run(this);
} else { } else {
@ -211,7 +228,7 @@ namespace ICSharpCode.NUnitPad
} }
} else { } else {
foreach (TreeNode node in treeView.Nodes) { foreach (TreeNode node in treeView.Nodes) {
Test test = node.Tag as Test; TestItemTag test = node.Tag as TestItemTag;
if (test != null) { if (test != null) {
test.Run(this); test.Run(this);
} else { } else {

5
src/Main/Base/Project/Src/Dom/IClass.cs

@ -105,7 +105,10 @@ namespace ICSharpCode.SharpDevelop.Dom
List<IClass> GetAccessibleTypes(IClass callingClass); List<IClass> GetAccessibleTypes(IClass callingClass);
//IMember SearchMember(string memberName); /// <summary>
/// Searches the member with the specified name. Returns the first member/overload found.
/// </summary>
IMember SearchMember(string memberName, LanguageProperties language);
/// <summary>Return true if the specified class is a base class of this class; otherwise return false.</summary> /// <summary>Return true if the specified class is a base class of this class; otherwise return false.</summary>
/// <remarks>Returns false when possibleBaseClass is null.</remarks> /// <remarks>Returns false when possibleBaseClass is null.</remarks>

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

@ -304,57 +304,42 @@ namespace ICSharpCode.SharpDevelop.Dom
return false; return false;
} }
/* /// <summary>
public IMember SearchMember(string memberName) /// Searches the member with the specified name. Returns the first member/overload found.
/// </summary>
public IMember SearchMember(string memberName, LanguageProperties language)
{ {
if (memberName == null || memberName.Length == 0) { if (memberName == null || memberName.Length == 0) {
return null; return null;
} }
foreach (IField f in Fields) { StringComparer cmp = language.NameComparer;
if (f.Name == memberName) {
return f;
}
}
foreach (IProperty p in Properties) { foreach (IProperty p in Properties) {
if (p.Name == memberName) { if (cmp.Equals(p.Name, memberName)) {
return p; return p;
} }
} }
foreach (IIndexer i in Indexer) {
if (i.Name == memberName) {
return i;
}
}
foreach (IEvent e in Events) { foreach (IEvent e in Events) {
if (e.Name == memberName) { if (cmp.Equals(e.Name, memberName)) {
return e; return e;
} }
} }
foreach (IMethod m in Methods) { foreach (IField f in Fields) {
if (m.Name == memberName) { if (cmp.Equals(f.Name, memberName)) {
return m; return f;
} }
} }
if (ClassType == ClassType.Interface) { foreach (IIndexer i in Indexer) {
foreach (string baseType in BaseTypes) { if (cmp.Equals(i.Name, memberName)) {
int line = -1; return i;
int col = -1; }
if (Region != null) { }
line = Region.BeginLine; foreach (IMethod m in Methods) {
col = Region.BeginColumn; if (cmp.Equals(m.Name, memberName)) {
} return m;
IClass c = ProjectContent.SearchType(baseType, this, line, col);
if (c != null) {
return c.SearchMember(memberName);
}
} }
} else {
IClass c = BaseClass;
return c.SearchMember(memberName);
} }
return null; return null;
} }
*/
public IClass GetInnermostClass(int caretLine, int caretColumn) public IClass GetInnermostClass(int caretLine, int caretColumn)
{ {

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

@ -1,4 +1,4 @@
// <file> // <file>
// <copyright see="prj:///doc/copyright.txt"/> // <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/> // <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/> // <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
@ -52,9 +52,10 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
foreach (KeyValuePair<string, string> entry in aliases) { foreach (KeyValuePair<string, string> entry in aliases) {
string aliasString = entry.Key; string aliasString = entry.Key;
// TODO: case insensitive: partitialNamespaceName.ToLower().StartsWith(aliasString.ToLower()) if (projectContent.Language.NameComparer.Equals(partitialNamespaceName, aliasString))
if (partitialNamespaceName.StartsWith(aliasString)) { return entry.Value;
if (aliasString.Length >= 0) { if (partitialNamespaceName.Length > aliasString.Length) {
if (projectContent.Language.NameComparer.Equals(partitialNamespaceName.Substring(0, aliasString.Length + 1), aliasString + ".")) {
string nsName = nsName = String.Concat(entry.Value, partitialNamespaceName.Remove(0, aliasString.Length)); string nsName = nsName = String.Concat(entry.Value, partitialNamespaceName.Remove(0, aliasString.Length));
if (projectContent.NamespaceExists(nsName)) { if (projectContent.NamespaceExists(nsName)) {
return nsName; return nsName;
@ -62,26 +63,23 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
} }
if (projectContent.Language.ImportNamespaces) {
foreach (string str in usings) {
string possibleNamespace = String.Concat(str, ".", partitialNamespaceName);
if (projectContent.NamespaceExists(possibleNamespace))
return possibleNamespace;
}
}
return null; return null;
} }
public IClass SearchType(string partitialTypeName) public IClass SearchType(string partitialTypeName)
{ {
foreach (string str in usings) {
string possibleType = String.Concat(str, ".", partitialTypeName);
IClass c = projectContent.GetClass(possibleType);
if (c != null) {
return c;
}
}
foreach (KeyValuePair<string, string> entry in aliases) { foreach (KeyValuePair<string, string> entry in aliases) {
string aliasString = entry.Key; string aliasString = entry.Key;
// TODO: case insensitive: : partitialTypeName.ToLower().StartsWith(aliasString.ToLower()) if (partitialTypeName.Length > aliasString.Length) {
if (partitialTypeName.StartsWith(aliasString)) { if (projectContent.Language.NameComparer.Equals(partitialTypeName.Substring(0, aliasString.Length + 1), aliasString + ".")) {
string className = null; string className = String.Concat(entry.Value, partitialTypeName.Remove(0, aliasString.Length));
if (aliasString.Length > 0) {
className = String.Concat(entry.Value, partitialTypeName.Remove(0, aliasString.Length));
IClass c = projectContent.GetClass(className); IClass c = projectContent.GetClass(className);
if (c != null) { if (c != null) {
return c; return c;
@ -89,12 +87,39 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
} }
if (projectContent.Language.ImportNamespaces) {
foreach (string str in usings) {
IClass c = projectContent.GetClass(str + "." + partitialTypeName);
if (c != null) {
return c;
}
}
} else {
int pos = partitialTypeName.IndexOf('.');
string className, subClassName;
if (pos < 0) {
className = partitialTypeName;
subClassName = null;
} else {
className = partitialTypeName.Substring(0, pos);
subClassName = partitialTypeName.Substring(pos + 1);
}
foreach (string str in usings) {
IClass c = projectContent.GetClass(str + "." + className);
if (c != null) {
c = projectContent.GetClass(str + "." + partitialTypeName);
if (c != null) {
return c;
}
}
}
}
return null; return null;
} }
public override string ToString() public override string ToString()
{ {
StringBuilder builder = new StringBuilder("[AbstractUsing: "); StringBuilder builder = new StringBuilder("[DefaultUsing: ");
foreach (string str in usings) { foreach (string str in usings) {
builder.Append(str); builder.Append(str);
builder.Append(", "); builder.Append(", ");

30
src/Main/Base/Project/Src/Dom/LanguageProperties.cs

@ -22,6 +22,17 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
return member.IsStatic || !showStatic; return member.IsStatic || !showStatic;
} }
public override bool ImportNamespaces {
get {
return true;
}
}
public override string ToString()
{
return "[LanguageProperties: VB.NET]";
}
} }
StringComparer nameComparer; StringComparer nameComparer;
@ -36,10 +47,27 @@ namespace ICSharpCode.SharpDevelop.Dom
return nameComparer; return nameComparer;
} }
} }
/// <summary>
/// Gets if namespaces can be imported (i.e. Imports System, Dim a As Collections.ArrayList)
/// </summary>
public virtual bool ImportNamespaces {
get {
return false;
}
}
public virtual bool ShowMember(IMember member, bool showStatic) public virtual bool ShowMember(IMember member, bool showStatic)
{ {
return member.IsStatic == showStatic; return member.IsStatic == showStatic;
} }
public override string ToString()
{
if (GetType() == typeof(LanguageProperties) && nameComparer == StringComparer.InvariantCulture)
return "[LanguageProperties: C#]";
else
return "[" + base.ToString() + "]";
}
} }
} }

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

@ -24,11 +24,11 @@ namespace ICSharpCode.Core
{ {
public class DefaultProjectContent : IProjectContent public class DefaultProjectContent : IProjectContent
{ {
List<IProjectContent> referencedContents = new List<IProjectContent>(); List<IProjectContent> referencedContents = new List<IProjectContent>();
List<Dictionary<string, IClass>> classLists = new List<Dictionary<string, IClass>>(); List<Dictionary<string, IClass>> classLists = new List<Dictionary<string, IClass>>();
Hashtable namespaces = new Hashtable(); List<Dictionary<string, NamespaceStruct>> namespaces = new List<Dictionary<string, NamespaceStruct>>();
protected XmlDoc xmlDoc = new XmlDoc(); protected XmlDoc xmlDoc = new XmlDoc();
public List<Dictionary<string, IClass>> ClassLists { public List<Dictionary<string, IClass>> ClassLists {
get { get {
@ -39,7 +39,28 @@ namespace ICSharpCode.Core
} }
} }
Dictionary<string, IClass> GetClasses(LanguageProperties language) protected List<Dictionary<string, NamespaceStruct>> Namespaces {
get {
if (namespaces.Count == 0) {
namespaces.Add(new Dictionary<string, NamespaceStruct>(language.NameComparer));
}
return namespaces;
}
}
protected struct NamespaceStruct
{
public readonly List<IClass> Classes;
public readonly List<string> SubNamespaces;
public NamespaceStruct(string name) // struct must have a parameter
{
this.Classes = new List<IClass>();
this.SubNamespaces = new List<string>();
}
}
protected Dictionary<string, IClass> GetClasses(LanguageProperties language)
{ {
for (int i = 0; i < classLists.Count; ++i) { for (int i = 0; i < classLists.Count; ++i) {
if (classLists[i].Comparer == language.NameComparer) if (classLists[i].Comparer == language.NameComparer)
@ -59,6 +80,26 @@ namespace ICSharpCode.Core
return d; return d;
} }
protected Dictionary<string, NamespaceStruct> GetNamespaces(LanguageProperties language)
{
for (int i = 0; i < namespaces.Count; ++i) {
if (namespaces[i].Comparer == language.NameComparer)
return namespaces[i];
}
Dictionary<string, NamespaceStruct> d;
if (namespaces.Count > 0) {
Dictionary<string, NamespaceStruct> oldList = namespaces[0];
d = new Dictionary<string, NamespaceStruct>(oldList.Count, language.NameComparer);
foreach (KeyValuePair<string, NamespaceStruct> pair in oldList) {
d.Add(pair.Key, pair.Value);
}
} else {
d = new Dictionary<string, NamespaceStruct>(language.NameComparer);
}
namespaces.Add(d);
return d;
}
public XmlDoc XmlDoc { public XmlDoc XmlDoc {
get { get {
return xmlDoc; return xmlDoc;
@ -130,14 +171,14 @@ namespace ICSharpCode.Core
xmlDoc.Dispose(); xmlDoc.Dispose();
} }
public Hashtable AddClassToNamespaceList(IClass addClass) public void AddClassToNamespaceList(IClass addClass)
{ {
lock (namespaces) { lock (namespaces) {
return AddClassToNamespaceListInternal(addClass); AddClassToNamespaceListInternal(addClass);
} }
} }
protected Hashtable AddClassToNamespaceListInternal(IClass addClass) protected void AddClassToNamespaceListInternal(IClass addClass)
{ {
foreach (Dictionary<string, IClass> classes in ClassLists) { foreach (Dictionary<string, IClass> classes in ClassLists) {
classes[addClass.FullyQualifiedName] = addClass; classes[addClass.FullyQualifiedName] = addClass;
@ -146,29 +187,75 @@ namespace ICSharpCode.Core
if (nSpace == null) { if (nSpace == null) {
nSpace = String.Empty; nSpace = String.Empty;
} }
CreateNamespace(nSpace);
Hashtable cur = namespaces; List<IClass> classList = GetNamespaces(this.language)[nSpace].Classes;
for (int i = 0; i < classList.Count; i++) {
if (nSpace.Length > 0) { if (classList[i].FullyQualifiedName == addClass.FullyQualifiedName) {
string[] path = nSpace.Split('.'); classList[i] = addClass;
for (int i = 0; i < path.Length; ++i) { return;
object curPath = cur[path[i]];
if (curPath == null) {
Hashtable hashTable = new Hashtable();
cur[path[i]] = curPath = hashTable;
} else {
if (!(curPath is Hashtable)) {
return null;
}
}
cur = (Hashtable)curPath;
} }
} }
classList.Add(addClass);
string name = addClass.Name == null ? "" : addClass.Name; }
cur[name] = addClass; void CreateNamespace(string nSpace)
return cur; {
Dictionary<string, NamespaceStruct> dict = GetNamespaces(this.language);
if (dict.ContainsKey(nSpace))
return;
NamespaceStruct namespaceStruct = new NamespaceStruct(nSpace);
dict.Add(nSpace, namespaceStruct);
// use the same namespaceStruct for all dictionaries
foreach (Dictionary<string, NamespaceStruct> otherDict in namespaces) {
if (otherDict == dict) continue;
otherDict.Add(nSpace, namespaceStruct);
}
if (nSpace.Length == 0)
return;
// add to parent namespace
int pos = nSpace.LastIndexOf('.');
string parent;
string subNs;
if (pos < 0) {
parent = "";
subNs = nSpace;
} else {
parent = nSpace.Substring(0, pos);
subNs = nSpace.Substring(pos + 1);
}
CreateNamespace(parent);
dict[parent].SubNamespaces.Add(subNs);
}
/// <summary>
/// Removes the specified namespace from all namespace lists if the namespace is empty.
/// </summary>
void RemoveEmptyNamespace(string nSpace)
{
if (nSpace == null || nSpace.Length == 0) return;
Dictionary<string, NamespaceStruct> dict = GetNamespaces(this.language);
if (!dict.ContainsKey(nSpace))
return;
// remove only if really empty
if (dict[nSpace].Classes.Count > 0 || dict[nSpace].SubNamespaces.Count > 0)
return;
// remove the namespace from all dictionaries
foreach (Dictionary<string, NamespaceStruct> anyDict in namespaces) {
anyDict.Remove(nSpace);
}
// remove the namespace from parent's SubNamespaces list
int pos = nSpace.LastIndexOf('.');
string parent;
string subNs;
if (pos < 0) {
parent = "";
subNs = nSpace;
} else {
parent = nSpace.Substring(0, pos);
subNs = nSpace.Substring(pos + 1);
}
dict[parent].SubNamespaces.Remove(subNs);
RemoveEmptyNamespace(parent); // remove parent if also empty
} }
public void UpdateCompilationUnit(ICompilationUnit oldUnit, ICompilationUnit parserOutput, string fileName, bool updateCommentTags) public void UpdateCompilationUnit(ICompilationUnit oldUnit, ICompilationUnit parserOutput, string fileName, bool updateCommentTags)
@ -178,26 +265,61 @@ namespace ICSharpCode.Core
} }
lock (namespaces) { lock (namespaces) {
ICompilationUnit cu = (ICompilationUnit)parserOutput;
if (oldUnit != null) { if (oldUnit != null) {
RemoveClasses(oldUnit); RemoveClasses(oldUnit, cu);
} }
ICompilationUnit cu = (ICompilationUnit)parserOutput;
foreach (IClass c in cu.Classes) { foreach (IClass c in cu.Classes) {
AddClassToNamespaceListInternal(c); AddClassToNamespaceListInternal(c);
} }
} }
} }
void RemoveClasses(ICompilationUnit cu) void RemoveClasses(ICompilationUnit oldUnit, ICompilationUnit newUnit)
{ {
if (cu != null) { foreach (IClass c in oldUnit.Classes) {
foreach (IClass c in cu.Classes) { bool found = false;
foreach (Dictionary<string, IClass> classes in ClassLists) { foreach (IClass c2 in newUnit.Classes) {
classes.Remove(c.FullyQualifiedName); if (c.FullyQualifiedName == c2.FullyQualifiedName) {
found = true;
break;
} }
} }
// TODO: remove classes from namespace lists if (!found) {
RemoveClass(c);
}
}
}
void RemoveClass(IClass @class)
{
string nSpace = @class.Namespace;
if (nSpace == null) {
nSpace = String.Empty;
}
RemoveClass(@class.FullyQualifiedName, nSpace);
}
void RemoveClass(string fullyQualifiedName, string nSpace)
{
foreach (Dictionary<string, IClass> classes in ClassLists) {
classes.Remove(fullyQualifiedName);
}
// 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) {
classList.RemoveAt(i);
break;
}
}
if (classList.Count == 0) {
RemoveEmptyNamespace(nSpace);
} }
} }
@ -209,7 +331,6 @@ namespace ICSharpCode.Core
public IClass GetClass(string typeName, LanguageProperties language, bool lookInReferences) public IClass GetClass(string typeName, LanguageProperties language, bool lookInReferences)
{ {
// Console.WriteLine("GetClass({0}) is known:{1}", typeName, classes.ContainsKey(typeName));
Dictionary<string, IClass> classes = GetClasses(language); Dictionary<string, IClass> classes = GetClasses(language);
if (classes.ContainsKey(typeName)) { if (classes.ContainsKey(typeName)) {
return classes[typeName]; return classes[typeName];
@ -245,46 +366,33 @@ namespace ICSharpCode.Core
return null; return null;
} }
public ArrayList GetNamespaceContents(string subNameSpace) public ArrayList GetNamespaceContents(string nameSpace)
{ {
ArrayList namespaceList = new ArrayList(); ArrayList namespaceList = new ArrayList();
AddNamespaceContents(namespaceList, subNameSpace, language, true); AddNamespaceContents(namespaceList, nameSpace, language, true);
return namespaceList; return namespaceList;
} }
public void AddNamespaceContents(ArrayList list, string subNameSpace, LanguageProperties language, bool lookInReferences) /// <summary>
/// Adds the contents of the specified <paramref name="nameSpace"/> to the <paramref name="list"/>.
/// </summary>
public void AddNamespaceContents(ArrayList list, string nameSpace, LanguageProperties language, bool lookInReferences)
{ {
if (subNameSpace == null) { if (nameSpace == null) {
return; return;
} }
if (lookInReferences) { if (lookInReferences) {
foreach (IProjectContent content in referencedContents) { foreach (IProjectContent content in referencedContents) {
content.AddNamespaceContents(list, subNameSpace, language, false); content.AddNamespaceContents(list, nameSpace, language, false);
} }
} }
Hashtable cur = namespaces; Dictionary<string, NamespaceStruct> dict = GetNamespaces(language);
if (dict.ContainsKey(nameSpace)) {
if (subNameSpace.Length > 0) { NamespaceStruct ns = dict[nameSpace];
string[] path = subNameSpace.Split('.'); list.AddRange(ns.Classes);
for (int i = 0; i < path.Length; ++i) { list.AddRange(ns.SubNamespaces);
if (!(cur[path[i]] is Hashtable)) {
// namespace does not exist in this project content
return;
}
cur = (Hashtable)cur[path[i]];
}
}
foreach (DictionaryEntry entry in cur) {
if (entry.Value is Hashtable) {
if (!list.Contains(entry.Key))
list.Add(entry.Key);
} else {
if (!list.Contains(entry.Value))
list.Add(entry.Value);
}
} }
} }
@ -307,21 +415,12 @@ namespace ICSharpCode.Core
} }
} }
string[] path = name.Split('.'); return GetNamespaces(language).ContainsKey(name);
Hashtable cur = namespaces;
for (int i = 0; i < path.Length; ++i) {
if (!(cur[path[i]] is Hashtable)) {
return false;
}
cur = (Hashtable)cur[path[i]];
}
return true;
} }
public string SearchNamespace(string name, ICompilationUnit unit, int caretLine, int caretColumn) public string SearchNamespace(string name, ICompilationUnit unit, int caretLine, int caretColumn)
{ {
// Console.WriteLine("SearchNamespace({0})", name);
if (NamespaceExists(name)) { if (NamespaceExists(name)) {
return name; return name;
} }
@ -350,7 +449,6 @@ namespace ICSharpCode.Core
public IClass SearchType(string name, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn) public IClass SearchType(string name, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn)
{ {
// Console.WriteLine("SearchType({0})", name);
if (name == null || name.Length == 0) { if (name == null || name.Length == 0) {
return null; return null;
} }
@ -376,6 +474,16 @@ namespace ICSharpCode.Core
// remove class name again to try next namespace // remove class name again to try next namespace
curnamespace.Length -= name.Length; curnamespace.Length -= name.Length;
} }
if (name.IndexOf('.') < 0) {
// Try inner classes of parent classes
while ((curType = curType.BaseClass) != null) {
foreach (IClass innerClass in curType.InnerClasses) {
if (language.NameComparer.Equals(innerClass.Name, name))
return innerClass;
}
}
}
} }
if (unit != null) { if (unit != null) {
// Combine name with usings // Combine name with usings
@ -391,114 +499,29 @@ namespace ICSharpCode.Core
return null; return null;
} }
/* /// <summary>
public ArrayList ListMembers(ArrayList members, IClass curType, IClass callingClass, bool showStatic) /// Gets the position of a member in this project content (not a referenced one).
{ /// </summary>
// Console.WriteLine("ListMembers()"); /// <param name="fullMemberName">Fully qualified member name (always case sensitive).</param>
DateTime now = DateTime.Now;
// enums must be handled specially, because there are several things defined we don't want to show
// and enum members have neither the modifier nor the modifier public
if (curType.ClassType == ClassType.Enum) {
foreach (IField f in curType.Fields) {
if (f.IsLiteral) {
members.Add(f);
}
}
ListMembers(members, GetClass("System.Enum"), callingClass, showStatic);
return members;
}
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType);
if (showStatic) {
foreach (IClass c in curType.InnerClasses) {
if (c.IsAccessible(callingClass, isClassInInheritanceTree)) {
members.Add(c);
}
}
}
foreach (IProperty p in curType.Properties) {
if (p.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) {
members.Add(p);
}
}
foreach (IMethod m in curType.Methods) {
if (m.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) {
members.Add(m);
}
}
foreach (IEvent e in curType.Events) {
if (e.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) {
members.Add(e);
}
}
foreach (IField f in curType.Fields) {
if (f.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) {
members.Add(f);
}
}
if (curType.ClassType == ClassType.Interface && !showStatic) {
foreach (string s in curType.BaseTypes) {
IClass baseClass = SearchType(s, curType, curType.Region != null ? curType.Region.BeginLine : -1, curType.Region != null ? curType.Region.BeginColumn : -1);
if (baseClass != null && baseClass.ClassType == ClassType.Interface) {
ListMembers(members, baseClass, callingClass, showStatic);
}
}
} else {
IClass baseClass = curType.BaseClass;
if (baseClass != null) {
ListMembers(members, baseClass, callingClass, showStatic);
}
}
return members;
}
*/
public Position GetPosition(string fullMemberName) public Position GetPosition(string fullMemberName)
{ {
string[] name = fullMemberName.Split(new char[] {'.'}); IClass curClass = GetClass(fullMemberName, LanguageProperties.CSharp, false);
string curName = name[0]; if (curClass != null) {
int i = 1; return new Position(curClass.CompilationUnit, curClass.Region != null ? curClass.Region.BeginLine : -1, curClass.Region != null ? curClass.Region.BeginColumn : -1);
while (i < name.Length && NamespaceExists(curName)) { }
curName += '.' + name[i]; int pos = fullMemberName.LastIndexOf('.');
++i; if (pos > 0) {
} string className = fullMemberName.Substring(0, pos);
Debug.Assert(i <= name.Length); string memberName = fullMemberName.Substring(pos + 1);
IClass curClass = GetClass(curName); curClass = GetClass(className, LanguageProperties.CSharp, false);
if (curClass == null) { if (curClass != null) {
return new Position(null, -1, -1); IMember member = curClass.SearchMember(memberName, LanguageProperties.CSharp);
} if (member != null) {
ICompilationUnit cu = curClass.CompilationUnit; return new Position(curClass.CompilationUnit, member.Region != null ? member.Region.BeginLine : -1, member.Region != null ? member.Region.BeginColumn : -1);
while (i < name.Length) {
List<IClass> innerClasses = curClass.InnerClasses;
foreach (IClass c in innerClasses) {
if (c.Name == name[i]) {
curClass = c;
break;
} }
} }
if (curClass.Name != name[i]) {
break;
}
++i;
}
if (i >= name.Length) {
return new Position(cu, curClass.Region != null ? curClass.Region.BeginLine : -1, curClass.Region != null ? curClass.Region.BeginColumn : -1);
}
return new Position(cu, -1, -1);
// TODO: reimplement this
/*IMember member = curClass.SearchMember(name[i]);
if (member == null || member.Region == null) {
return new Position(cu, -1, -1);
} }
return new Position(cu, member.Region.BeginLine, member.Region.BeginColumn);*/ return new Position(null, -1, -1);
} }
#endregion #endregion
} }

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

@ -43,15 +43,18 @@ namespace ICSharpCode.Core
string GetXmlDocumentation(string memberTag); string GetXmlDocumentation(string memberTag);
Hashtable AddClassToNamespaceList(IClass addClass); void AddClassToNamespaceList(IClass addClass);
void UpdateCompilationUnit(ICompilationUnit oldUnit, ICompilationUnit parserOutput, string fileName, bool updateCommentTags); void UpdateCompilationUnit(ICompilationUnit oldUnit, ICompilationUnit parserOutput, string fileName, bool updateCommentTags);
IClass GetClass(string typeName); IClass GetClass(string typeName);
bool NamespaceExists(string name); bool NamespaceExists(string name);
ArrayList GetNamespaceContents(string subNameSpace); ArrayList GetNamespaceContents(string nameSpace);
IClass GetClass(string typeName, LanguageProperties language, bool lookInReferences); IClass GetClass(string typeName, LanguageProperties language, bool lookInReferences);
bool NamespaceExists(string name, 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"/>.
/// </summary>
void AddNamespaceContents(ArrayList list, string subNameSpace, LanguageProperties language, bool lookInReferences); void AddNamespaceContents(ArrayList list, string subNameSpace, LanguageProperties language, bool lookInReferences);
string SearchNamespace(string name, ICompilationUnit unit, int caretLine, int caretColumn); string SearchNamespace(string name, ICompilationUnit unit, int caretLine, int caretColumn);

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

@ -614,7 +614,7 @@ class Activator {
{ {
// using an import in this way is not possible in C# // using an import in this way is not possible in C#
string program = @"using System; string program = @"using System;
class A { class TestClass {
void Test() { void Test() {
Collections.ArrayList a; Collections.ArrayList a;
@ -625,8 +625,7 @@ class A {
Assert.IsNull(result, "Collections.ArrayList should not resolve"); Assert.IsNull(result, "Collections.ArrayList should not resolve");
LocalResolveResult local = Resolve(program, "a", 5) as LocalResolveResult; LocalResolveResult local = Resolve(program, "a", 5) as LocalResolveResult;
Assert.IsNotNull(local, "a should resolve to a local variable"); Assert.IsNotNull(local, "a should resolve to a local variable");
Assert.AreEqual("Collections.ArrayList", local.ResolvedType.FullyQualifiedName, Assert.IsNull(local.ResolvedType, "the full type should not be resolved");
"the full type should not be resolved");
} }
[Test] [Test]
@ -634,10 +633,10 @@ class A {
{ {
// using an import this way IS possible in VB.NET // using an import this way IS possible in VB.NET
string program = @"Imports System string program = @"Imports System
Class A Class TestClass
Sub Test() Sub Test()
Dim a As Collections.ArrayList Dim a As Collections.ArrayList
End Sub End Sub
End Class End Class
"; ";
@ -653,8 +652,8 @@ End Class
[Test] [Test]
public void ImportAliasTest() public void ImportAliasTest()
{ {
string program = @"using System.Collections = COL; string program = @"using COL = System.Collections;
class A { class TestClass {
void Test() { void Test() {
COL.ArrayList a; COL.ArrayList a;
@ -674,7 +673,7 @@ class A {
public void ImportAliasNamespaceResolveTest() public void ImportAliasNamespaceResolveTest()
{ {
NamespaceResolveResult ns; NamespaceResolveResult ns;
string program = "using System.Collections = COL;\r\nclass A {\r\n}\r\n"; string program = "using COL = System.Collections;\r\nclass A {\r\n}\r\n";
ns = Resolve(program, "COL", 3) as NamespaceResolveResult; ns = Resolve(program, "COL", 3) as NamespaceResolveResult;
Assert.AreEqual("System.Collections", ns.Name, "COL"); Assert.AreEqual("System.Collections", ns.Name, "COL");
ns = Resolve(program, "COL.Generic", 3) as NamespaceResolveResult; ns = Resolve(program, "COL.Generic", 3) as NamespaceResolveResult;

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

@ -23,7 +23,10 @@ namespace ICSharpCode.SharpDevelop.Tests
pc.ReferencedContents.Add(ProjectContentRegistry.GetMscorlibContent()); pc.ReferencedContents.Add(ProjectContentRegistry.GetMscorlibContent());
pc.Language = language; pc.Language = language;
DefaultCompilationUnit cu = new DefaultCompilationUnit(pc); DefaultCompilationUnit cu = new DefaultCompilationUnit(pc);
cu.Usings.Add(CreateUsing(pc, "System")); if (language == LanguageProperties.VBNet)
cu.Usings.Add(CreateUsing(pc, "syStEm"));
else
cu.Usings.Add(CreateUsing(pc, "System"));
return cu; return cu;
} }
@ -37,25 +40,39 @@ namespace ICSharpCode.SharpDevelop.Tests
IClass SearchType(string type) IClass SearchType(string type)
{ {
ICompilationUnit cu = Prepare(LanguageProperties.CSharp); ICompilationUnit cu = Prepare(LanguageProperties.CSharp);
return cu.ProjectContent.SearchType(type, null, 1, 1); IClass c = cu.ProjectContent.SearchType(type, null, cu, 1, 1);
Assert.IsNotNull(c, type + "not found");
return c;
} }
IClass SearchTypeVB(string type) IClass SearchTypeVB(string type)
{ {
ICompilationUnit cu = Prepare(LanguageProperties.VBNet); ICompilationUnit cu = Prepare(LanguageProperties.VBNet);
return cu.ProjectContent.SearchType(type, null, 1, 1); IClass c = cu.ProjectContent.SearchType(type, null, cu, 1, 1);
Assert.IsNotNull(c, type + "not found");
return c;
} }
string SearchNamespace(string @namespace) void CheckNamespace(string @namespace, string className)
{ {
ICompilationUnit cu = Prepare(LanguageProperties.CSharp); CheckNamespace(@namespace, className, LanguageProperties.CSharp);
return cu.ProjectContent.SearchNamespace(@namespace, null, 1, 1);
} }
string SearchNamespaceVB(string @namespace) void CheckNamespaceVB(string @namespace, string className)
{ {
ICompilationUnit cu = Prepare(LanguageProperties.VBNet); CheckNamespace(@namespace, className, LanguageProperties.VBNet);
return cu.ProjectContent.SearchNamespace(@namespace, null, 1, 1); }
void CheckNamespace(string @namespace, string className, LanguageProperties language)
{
ICompilationUnit cu = Prepare(language);
string ns = cu.ProjectContent.SearchNamespace(@namespace, cu, 1, 1);
Assert.IsNotNull(ns, @namespace + " not found");
foreach (object o in cu.ProjectContent.GetNamespaceContents(ns)) {
IClass c = o as IClass;
if (c != null && c.Name == className)
return;
}
} }
#endregion #endregion
@ -74,13 +91,13 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void SearchFullyQualifiedNamespace() public void SearchFullyQualifiedNamespace()
{ {
Assert.AreEqual("System.Collections.Generic", SearchNamespace("System.Collections.Generic")); CheckNamespace("System.Collections.Generic", "KeyNotFoundException");
} }
[Test] [Test]
public void SearchFullyQualifiedNamespaceVB() public void SearchFullyQualifiedNamespaceVB()
{ {
Assert.AreEqual("System.Collections.Generic", SearchNamespace("SyStem.COllEctions.GeNEric")); CheckNamespaceVB("SyStem.COllEctions.GeNEric", "KeyNotFoundException");
} }
[Test] [Test]
@ -92,7 +109,35 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void SearchEnvironmentVB() public void SearchEnvironmentVB()
{ {
Assert.AreEqual("System.Environment", SearchType("EnVIroNmEnt").FullyQualifiedName); Assert.AreEqual("System.Environment", SearchTypeVB("EnVIroNmEnt").FullyQualifiedName);
}
[Test]
public void SearchArrayList()
{
ICompilationUnit cu = Prepare(LanguageProperties.CSharp);
IClass c = cu.ProjectContent.SearchType("Collections.ArrayList", null, cu, 1, 1);
Assert.IsNull(c, "Namespaces should not be imported in C#");
}
[Test]
public void SearchArrayListVB()
{
Assert.AreEqual("System.Collections.ArrayList", SearchTypeVB("CoLLections.ArrAyLiSt").FullyQualifiedName);
}
[Test]
public void SearchNestedNamespace()
{
ICompilationUnit cu = Prepare(LanguageProperties.CSharp);
string ns = cu.ProjectContent.SearchNamespace("Collections.Generic", cu, 1, 1);
Assert.IsNull(ns, "Nested namespaces should not be found in C#");
}
[Test]
public void SearchNestedNamespaceVB()
{
CheckNamespaceVB("COllEctions.GeNEric", "KeyNotFoundException");
} }
} }
} }

Loading…
Cancel
Save