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

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

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

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

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

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

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

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

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

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

@ -22,6 +22,17 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -22,6 +22,17 @@ namespace ICSharpCode.SharpDevelop.Dom
{
return member.IsStatic || !showStatic;
}
public override bool ImportNamespaces {
get {
return true;
}
}
public override string ToString()
{
return "[LanguageProperties: VB.NET]";
}
}
StringComparer nameComparer;
@ -36,10 +47,27 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -36,10 +47,27 @@ namespace ICSharpCode.SharpDevelop.Dom
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)
{
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 @@ -24,11 +24,11 @@ namespace ICSharpCode.Core
{
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>>();
Hashtable namespaces = new Hashtable();
protected XmlDoc xmlDoc = new XmlDoc();
List<Dictionary<string, NamespaceStruct>> namespaces = new List<Dictionary<string, NamespaceStruct>>();
protected XmlDoc xmlDoc = new XmlDoc();
public List<Dictionary<string, IClass>> ClassLists {
get {
@ -39,7 +39,28 @@ namespace ICSharpCode.Core @@ -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) {
if (classLists[i].Comparer == language.NameComparer)
@ -59,6 +80,26 @@ namespace ICSharpCode.Core @@ -59,6 +80,26 @@ namespace ICSharpCode.Core
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 {
get {
return xmlDoc;
@ -130,14 +171,14 @@ namespace ICSharpCode.Core @@ -130,14 +171,14 @@ namespace ICSharpCode.Core
xmlDoc.Dispose();
}
public Hashtable AddClassToNamespaceList(IClass addClass)
public void AddClassToNamespaceList(IClass addClass)
{
lock (namespaces) {
return AddClassToNamespaceListInternal(addClass);
AddClassToNamespaceListInternal(addClass);
}
}
protected Hashtable AddClassToNamespaceListInternal(IClass addClass)
protected void AddClassToNamespaceListInternal(IClass addClass)
{
foreach (Dictionary<string, IClass> classes in ClassLists) {
classes[addClass.FullyQualifiedName] = addClass;
@ -146,29 +187,75 @@ namespace ICSharpCode.Core @@ -146,29 +187,75 @@ namespace ICSharpCode.Core
if (nSpace == null) {
nSpace = String.Empty;
}
Hashtable cur = namespaces;
if (nSpace.Length > 0) {
string[] path = nSpace.Split('.');
for (int i = 0; i < path.Length; ++i) {
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;
CreateNamespace(nSpace);
List<IClass> classList = GetNamespaces(this.language)[nSpace].Classes;
for (int i = 0; i < classList.Count; i++) {
if (classList[i].FullyQualifiedName == addClass.FullyQualifiedName) {
classList[i] = addClass;
return;
}
}
string name = addClass.Name == null ? "" : addClass.Name;
cur[name] = addClass;
return cur;
classList.Add(addClass);
}
void CreateNamespace(string nSpace)
{
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)
@ -178,26 +265,61 @@ namespace ICSharpCode.Core @@ -178,26 +265,61 @@ namespace ICSharpCode.Core
}
lock (namespaces) {
ICompilationUnit cu = (ICompilationUnit)parserOutput;
if (oldUnit != null) {
RemoveClasses(oldUnit);
RemoveClasses(oldUnit, cu);
}
ICompilationUnit cu = (ICompilationUnit)parserOutput;
foreach (IClass c in cu.Classes) {
AddClassToNamespaceListInternal(c);
}
}
}
void RemoveClasses(ICompilationUnit cu)
void RemoveClasses(ICompilationUnit oldUnit, ICompilationUnit newUnit)
{
if (cu != null) {
foreach (IClass c in cu.Classes) {
foreach (Dictionary<string, IClass> classes in ClassLists) {
classes.Remove(c.FullyQualifiedName);
foreach (IClass c in oldUnit.Classes) {
bool found = false;
foreach (IClass c2 in newUnit.Classes) {
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 @@ -209,7 +331,6 @@ namespace ICSharpCode.Core
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);
if (classes.ContainsKey(typeName)) {
return classes[typeName];
@ -245,46 +366,33 @@ namespace ICSharpCode.Core @@ -245,46 +366,33 @@ namespace ICSharpCode.Core
return null;
}
public ArrayList GetNamespaceContents(string subNameSpace)
public ArrayList GetNamespaceContents(string nameSpace)
{
ArrayList namespaceList = new ArrayList();
AddNamespaceContents(namespaceList, subNameSpace, language, true);
AddNamespaceContents(namespaceList, nameSpace, language, true);
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;
}
if (lookInReferences) {
foreach (IProjectContent content in referencedContents) {
content.AddNamespaceContents(list, subNameSpace, language, false);
content.AddNamespaceContents(list, nameSpace, language, false);
}
}
Hashtable cur = namespaces;
if (subNameSpace.Length > 0) {
string[] path = subNameSpace.Split('.');
for (int i = 0; i < path.Length; ++i) {
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);
}
Dictionary<string, NamespaceStruct> dict = GetNamespaces(language);
if (dict.ContainsKey(nameSpace)) {
NamespaceStruct ns = dict[nameSpace];
list.AddRange(ns.Classes);
list.AddRange(ns.SubNamespaces);
}
}
@ -307,21 +415,12 @@ namespace ICSharpCode.Core @@ -307,21 +415,12 @@ namespace ICSharpCode.Core
}
}
string[] path = name.Split('.');
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;
return GetNamespaces(language).ContainsKey(name);
}
public string SearchNamespace(string name, ICompilationUnit unit, int caretLine, int caretColumn)
{
// Console.WriteLine("SearchNamespace({0})", name);
if (NamespaceExists(name)) {
return name;
}
@ -350,7 +449,6 @@ namespace ICSharpCode.Core @@ -350,7 +449,6 @@ namespace ICSharpCode.Core
public IClass SearchType(string name, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn)
{
// Console.WriteLine("SearchType({0})", name);
if (name == null || name.Length == 0) {
return null;
}
@ -376,6 +474,16 @@ namespace ICSharpCode.Core @@ -376,6 +474,16 @@ namespace ICSharpCode.Core
// remove class name again to try next namespace
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) {
// Combine name with usings
@ -391,114 +499,29 @@ namespace ICSharpCode.Core @@ -391,114 +499,29 @@ namespace ICSharpCode.Core
return null;
}
/*
public ArrayList ListMembers(ArrayList members, IClass curType, IClass callingClass, bool showStatic)
{
// Console.WriteLine("ListMembers()");
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;
}
*/
/// <summary>
/// Gets the position of a member in this project content (not a referenced one).
/// </summary>
/// <param name="fullMemberName">Fully qualified member name (always case sensitive).</param>
public Position GetPosition(string fullMemberName)
{
string[] name = fullMemberName.Split(new char[] {'.'});
string curName = name[0];
int i = 1;
while (i < name.Length && NamespaceExists(curName)) {
curName += '.' + name[i];
++i;
}
Debug.Assert(i <= name.Length);
IClass curClass = GetClass(curName);
if (curClass == null) {
return new Position(null, -1, -1);
}
ICompilationUnit cu = curClass.CompilationUnit;
while (i < name.Length) {
List<IClass> innerClasses = curClass.InnerClasses;
foreach (IClass c in innerClasses) {
if (c.Name == name[i]) {
curClass = c;
break;
IClass curClass = GetClass(fullMemberName, LanguageProperties.CSharp, false);
if (curClass != null) {
return new Position(curClass.CompilationUnit, curClass.Region != null ? curClass.Region.BeginLine : -1, curClass.Region != null ? curClass.Region.BeginColumn : -1);
}
int pos = fullMemberName.LastIndexOf('.');
if (pos > 0) {
string className = fullMemberName.Substring(0, pos);
string memberName = fullMemberName.Substring(pos + 1);
curClass = GetClass(className, LanguageProperties.CSharp, false);
if (curClass != null) {
IMember member = curClass.SearchMember(memberName, LanguageProperties.CSharp);
if (member != null) {
return new Position(curClass.CompilationUnit, member.Region != null ? member.Region.BeginLine : -1, member.Region != null ? member.Region.BeginColumn : -1);
}
}
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
}

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

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

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

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

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

@ -23,7 +23,10 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -23,7 +23,10 @@ namespace ICSharpCode.SharpDevelop.Tests
pc.ReferencedContents.Add(ProjectContentRegistry.GetMscorlibContent());
pc.Language = language;
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;
}
@ -37,25 +40,39 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -37,25 +40,39 @@ namespace ICSharpCode.SharpDevelop.Tests
IClass SearchType(string type)
{
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)
{
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);
return cu.ProjectContent.SearchNamespace(@namespace, null, 1, 1);
CheckNamespace(@namespace, className, LanguageProperties.CSharp);
}
string SearchNamespaceVB(string @namespace)
void CheckNamespaceVB(string @namespace, string className)
{
ICompilationUnit cu = Prepare(LanguageProperties.VBNet);
return cu.ProjectContent.SearchNamespace(@namespace, null, 1, 1);
CheckNamespace(@namespace, className, LanguageProperties.VBNet);
}
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
@ -74,13 +91,13 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -74,13 +91,13 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test]
public void SearchFullyQualifiedNamespace()
{
Assert.AreEqual("System.Collections.Generic", SearchNamespace("System.Collections.Generic"));
CheckNamespace("System.Collections.Generic", "KeyNotFoundException");
}
[Test]
public void SearchFullyQualifiedNamespaceVB()
{
Assert.AreEqual("System.Collections.Generic", SearchNamespace("SyStem.COllEctions.GeNEric"));
CheckNamespaceVB("SyStem.COllEctions.GeNEric", "KeyNotFoundException");
}
[Test]
@ -92,7 +109,35 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -92,7 +109,35 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test]
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