Browse Source

Added new ResolveResult that gives information about the expression being resolved.

Currently it is used for code completion and method insight.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@72 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 21 years ago
parent
commit
bd51ecf13e
  1. 3
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  2. 102
      src/Main/Base/Project/Src/Dom/IParser.cs
  3. 4
      src/Main/Base/Project/Src/Dom/Implementations/AbstractClass.cs
  4. 7
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryASTConvertVisitor.cs
  5. 660
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
  6. 26
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs
  7. 295
      src/Main/Base/Project/Src/Dom/ResolveResult.cs
  8. 2
      src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
  9. 3
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionDataProvider.cs
  10. 1
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CommentCompletionDataProvider.cs
  11. 3
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/IndexerInsightDataProvider.cs
  12. 96
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs
  13. 16
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextAreaControl.cs
  14. 4
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs

3
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -1,4 +1,4 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -618,6 +618,7 @@
<Compile Include="Src\Dom\XmlDoc.cs" /> <Compile Include="Src\Dom\XmlDoc.cs" />
<Compile Include="Src\Services\ParserService\ProjectContentRegistry.cs" /> <Compile Include="Src\Services\ParserService\ProjectContentRegistry.cs" />
<Compile Include="Src\Dom\NRefactoryResolver\FilePosition.cs" /> <Compile Include="Src\Dom\NRefactoryResolver\FilePosition.cs" />
<Compile Include="Src\Dom\ResolveResult.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj"> <ProjectReference Include="..\..\..\Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj">

102
src/Main/Base/Project/Src/Dom/IParser.cs

@ -14,110 +14,9 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
// [Flags]
// public enum ShowMembers {
// Public = 1,
// Protected = 2,
// Private = 4,
// Static = 8
// }
public class ResolveResult
{
IClass type;
ArrayList members;
List<string> namespaces;
public IClass Type {
get {
return type;
}
}
public ArrayList Members {
get {
return members;
}
}
public List<string> Namespaces {
get {
return namespaces;
}
}
public ResolveResult(string[] namespaces) {
this.namespaces = new List<string>();
this.namespaces.AddRange(namespaces);
members = new ArrayList();
}
public ResolveResult(string[] namespaces, ArrayList classes) {
this.namespaces = new List<string>();
this.namespaces.AddRange(namespaces);
members = classes;
}
public ResolveResult(List<string> namespaces) {
this.namespaces = namespaces;
members = new ArrayList();
}
public ResolveResult(IClass type, ArrayList members) {
this.type = type;
this.members = members;
namespaces = new List<string>();
}
// object[] resolveContents;
// ShowMembers showMembers;
//
// public bool ShowPublic {
// get {
// return (showMembers & ShowMembers.Public) == ShowMembers.Public;
// }
// }
//
// public bool ShowProtected {
// get {
// return (showMembers & ShowMembers.Protected) == ShowMembers.Protected;
// }
// }
//
// public bool ShowPrivate {
// get {
// return (showMembers & ShowMembers.Private) == ShowMembers.Private;
// }
// }
//
// public bool ShowStatic {
// get {
// return (showMembers & ShowMembers.Static) == ShowMembers.Static;
// }
// }
//
// public object[] ResolveContents {
// get {
// return resolveContents;
// }
// }
//
// public ShowMembers ShowMembers {
// get {
// return showMembers;
// }
// }
//
// public ResolveResult(object[] resolveContents, ShowMembers showMembers)
// {
// this.resolveContents = resolveContents;
// this.showMembers = showMembers;
// }
}
public interface IParser { public interface IParser {
string[] LexerTags { string[] LexerTags {
//// Alex - need to have get accessor too
get; get;
set; set;
} }
@ -132,6 +31,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// extension. /// extension.
/// </summary> /// </summary>
bool CanParse(string fileName); bool CanParse(string fileName);
/// <summary> /// <summary>
/// Gets if the parser can parse the specified project. /// Gets if the parser can parse the specified project.
/// Only when no parser for a project is found, the assembly is loaded. /// Only when no parser for a project is found, the assembly is loaded.

4
src/Main/Base/Project/Src/Dom/Implementations/AbstractClass.cs

@ -362,7 +362,9 @@ namespace ICSharpCode.SharpDevelop.Dom
return members; return members;
} }
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(this); bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(this);
if (showStatic) { if (showStatic) {
foreach (IClass c in InnerClasses) { foreach (IClass c in InnerClasses) {

7
src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryASTConvertVisitor.cs

@ -303,7 +303,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
for (int i = 0; i < fieldDeclaration.Fields.Count; ++i) { for (int i = 0; i < fieldDeclaration.Fields.Count; ++i) {
AST.VariableDeclaration field = (AST.VariableDeclaration)fieldDeclaration.Fields[i]; AST.VariableDeclaration field = (AST.VariableDeclaration)fieldDeclaration.Fields[i];
Field f = new Field(new ReturnType(fieldDeclaration.GetTypeForField(i)), field.Name, fieldDeclaration.Modifier, region, GetCurrentClass()); ReturnType retType;
if (c.ClassType == ClassType.Enum)
retType = new ReturnType(c.FullyQualifiedName);
else
retType = new ReturnType(fieldDeclaration.GetTypeForField(i));
Field f = new Field(retType, field.Name, fieldDeclaration.Modifier, region, GetCurrentClass());
f.Attributes.AddRange(VisitAttributes(fieldDeclaration.Attributes)); f.Attributes.AddRange(VisitAttributes(fieldDeclaration.Attributes));
if (c.ClassType == ClassType.Enum) { if (c.ClassType == ClassType.Enum) {
f.SetModifiers(ModifierEnum.Const | ModifierEnum.SpecialName); f.SetModifiers(ModifierEnum.Const | ModifierEnum.SpecialName);

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

@ -21,12 +21,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{ {
ICompilationUnit cu; ICompilationUnit cu;
IClass callingClass; IClass callingClass;
IMember callingMember;
ICSharpCode.NRefactory.Parser.LookupTableVisitor lookupTableVisitor; ICSharpCode.NRefactory.Parser.LookupTableVisitor lookupTableVisitor;
IProjectContent projectContent = null; IProjectContent projectContent = null;
bool showStatic = false;
bool inNew = false;
bool caseSensitive = true; bool caseSensitive = true;
SupportedLanguages language = SupportedLanguages.CSharp; SupportedLanguages language = SupportedLanguages.CSharp;
@ -60,16 +58,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
} }
public bool ShowStatic {
get {
return showStatic;
}
set {
showStatic = value;
}
}
public NRefactoryResolver(SupportedLanguages language) public NRefactoryResolver(SupportedLanguages language)
{ {
this.language = language; this.language = language;
@ -103,21 +91,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
expression = expression.ToLower(); expression = expression.ToLower();
} }
// disable the code completion for numbers like 3.47
if (IsNumber(expression)) {
return null;
}
if (expression.StartsWith("new ")) {
inNew = true;
expression = expression.Substring(4);
} else {
inNew = false;
}
if (expression.StartsWith(GetUsingString())) {
return UsingResolve(expression);
}
this.caretLine = caretLineNumber; this.caretLine = caretLineNumber;
this.caretColumn = caretColumn; this.caretColumn = caretColumn;
@ -156,40 +129,147 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (cu != null) { if (cu != null) {
callingClass = cu.GetInnermostClass(caretLine, caretColumn); callingClass = cu.GetInnermostClass(caretLine, caretColumn);
} }
callingMember = GetCurrentMember();
TypeVisitor typeVisitor = new TypeVisitor(this); TypeVisitor typeVisitor = new TypeVisitor(this);
if (expr is InvocationExpression) {
IMethod method = typeVisitor.GetMethod((InvocationExpression)expr, null);
if (method != null)
return new MemberResolveResult(callingClass, callingMember, method);
} else if (expr is FieldReferenceExpression) {
FieldReferenceExpression fieldReferenceExpression = (FieldReferenceExpression)expr;
IReturnType returnType = fieldReferenceExpression.TargetObject.AcceptVisitor(typeVisitor, null) as IReturnType;
if (returnType != null) {
string name = SearchNamespace(returnType.FullyQualifiedName, this.CompilationUnit);
if (name != null) {
name += "." + fieldReferenceExpression.FieldName;
string n = SearchNamespace(name, null);
if (n != null) {
return new NamespaceResolveResult(callingClass, callingMember, n);
}
IClass c = SearchType(name, this.CallingClass, this.CompilationUnit);
if (c != null) {
return new TypeResolveResult(callingClass, callingMember, new ReturnType(c.FullyQualifiedName), c);
}
return null;
}
IMember member = GetMember(returnType, fieldReferenceExpression.FieldName);
if (member != null)
return new MemberResolveResult(callingClass, callingMember, member);
ResolveResult result = ResolveMethod(returnType, fieldReferenceExpression.FieldName);
if (result != null)
return result;
}
} else if (expr is IdentifierExpression) {
ResolveResult result = ResolveIdentifier(((IdentifierExpression)expr).Identifier);
if (result != null)
return result;
}
IReturnType type = expr.AcceptVisitor(typeVisitor, null) as IReturnType; IReturnType type = expr.AcceptVisitor(typeVisitor, null) as IReturnType;
if (type == null || type.FullyQualifiedName == "" || type.PointerNestingLevel != 0) { if (type == null || type.FullyQualifiedName == "" || type.PointerNestingLevel != 0) {
return null; return null;
} }
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) { if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0)
type = new ReturnType("System.Array"); return new ResolveResult(callingClass, callingMember, new ReturnType("System.Array"));
else {
return new ResolveResult(callingClass, callingMember, FixType(type));
}
} }
IReturnType FixType(IReturnType type)
{
IClass returnClass = SearchType(type.FullyQualifiedName, callingClass, cu); IClass returnClass = SearchType(type.FullyQualifiedName, callingClass, cu);
if (returnClass == null) { if (returnClass != null && returnClass.FullyQualifiedName != type.FullyQualifiedName)
return TryNamespace(type); return new ReturnType(returnClass.FullyQualifiedName);
else
return type;
}
#region Resolve Identifier
ResolveResult ResolveIdentifier(string identifier)
{
string name = SearchNamespace(identifier, this.CompilationUnit);
if (name != null && name != "") {
return new NamespaceResolveResult(callingClass, callingMember, name);
}
IClass c = SearchType(identifier, this.CallingClass, this.CompilationUnit);
if (c != null) {
return new TypeResolveResult(callingClass, callingMember, new ReturnType(c.FullyQualifiedName), c);
}
LocalLookupVariable var = SearchVariable(identifier);
if (var != null) {
IReturnType type = GetVariableType(var);
IField field = new LocalVariableField(type, identifier, null, callingClass);
return new LocalResolveResult(callingClass, callingMember, field, false);
}
IParameter para = SearchMethodParameter(identifier);
if (para != null) {
IField field = new LocalVariableField(para.ReturnType, para.Name, para.Region, callingClass);
return new LocalResolveResult(callingClass, callingMember, field, true);
}
IMember member = GetMember(callingClass, identifier);
if (member != null) {
return new MemberResolveResult(callingClass, callingMember, member);
}
ResolveResult result = ResolveMethod(callingClass, identifier);
if (result != null)
return result;
// try if there exists a static member in outer classes named typeName
List<IClass> classes = cu.GetOuterClasses(caretLine, caretColumn);
foreach (IClass c2 in classes) {
member = GetMember(c2, identifier);
if (member != null && member.IsStatic) {
return new MemberResolveResult(callingClass, callingMember, member);
}
}
return null;
}
private class LocalVariableField : AbstractField
{
public LocalVariableField(IReturnType type, string name, IRegion region, IClass declaringType) : base(declaringType)
{
this.returnType = type;
this.FullyQualifiedName = name;
this.region = region;
this.modifiers = ModifierEnum.Private;
}
}
#endregion
#region ResolveMethod
ResolveResult ResolveMethod(IReturnType type, string identifier)
{
if (type == null || type.PointerNestingLevel != 0) {
return null;
} }
if (inNew) { IClass curType;
return new ResolveResult(returnClass, returnClass.GetAccessibleTypes(callingClass)); if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) {
curType = SearchType("System.Array", null, null);
} else { } else {
ArrayList result = returnClass.GetAccessibleMembers(callingClass, showStatic); curType = SearchType(type.FullyQualifiedName, null, null);
if (!showStatic && language == SupportedLanguages.VBNet) { if (curType == null) {
result.AddRange(returnClass.GetAccessibleMembers(callingClass, true).ToArray()); return null;
} }
return new ResolveResult(returnClass, result);
} }
return ResolveMethod(curType, identifier);
} }
bool IsNumber(string expression) ResolveResult ResolveMethod(IClass c, string identifier)
{ {
try { foreach (IClass curType in c.ClassInheritanceTree) {
int.Parse(expression); foreach (IMethod method in c.Methods) {
return true; if (IsSameName(identifier, method.Name))
} catch (Exception) { return new MethodResolveResult(callingClass, callingMember, c, identifier);
return false;
} }
} }
return null;
}
#endregion
Expression WithResolve() Expression WithResolve()
{ {
@ -208,121 +288,107 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return expr; return expr;
} }
string GetUsingString() Expression SpecialConstructs(string expression)
{
switch (language) {
case SupportedLanguages.CSharp:
return "using ";
case SupportedLanguages.VBNet:
return "imports ";
default:
throw new NotSupportedException("The language " + language + " is not supported in the resolver");
}
}
ResolveResult ImportsResolve(string expression)
{ {
// expression[expression.Length - 1] != '.' if (language == SupportedLanguages.VBNet) {
// the period that causes this Resove() is not part of the expression // MyBase and MyClass are no expressions, only MyBase.Identifier and MyClass.Identifier
if (expression[expression.Length - 1] == '.') { if (expression == "mybase") {
return null; return new BaseReferenceExpression();
} } else if (expression == "myclass") {
int i; return new ClassReferenceExpression();
for (i = expression.Length - 1; i >= 0; --i) {
if (!(Char.IsLetterOrDigit(expression[i]) || expression[i] == '_' || expression[i] == '.')) {
break;
}
} }
// no Identifier before the period
if (i == expression.Length - 1) {
return null;
} }
string t = expression.Substring(i + 1);
string[] namespaces = projectContent.GetNamespaceList(t);
if (namespaces == null || namespaces.Length <= 0) {
return null; return null;
} }
return new ResolveResult(namespaces);
}
ResolveResult UsingResolve(string expression) bool IsSameName(string name1, string name2)
{ {
if (language == SupportedLanguages.VBNet) { if (IsCaseSensitive(language)) {
return ImportsResolve(expression); return name1 == name2;
} else {
return name1.ToLower() == name2.ToLower();
} }
// expression[expression.Length - 1] != '.'
// the period that causes this Resove() is not part of the expression
if (expression[expression.Length - 1] == '.') {
return null;
} }
int i;
for (i = expression.Length - 1; i >= 0; --i) { bool IsInside(Point between, Point start, Point end)
if (!(Char.IsLetterOrDigit(expression[i]) || expression[i] == '_' || expression[i] == '.')) { {
break; if (between.Y < start.Y || between.Y > end.Y) {
return false;
} }
if (between.Y > start.Y) {
if (between.Y < end.Y) {
return true;
} }
// no Identifier before the period // between.Y == end.Y
if (i == expression.Length - 1) { return between.X <= end.X;
return null;
} }
string t = expression.Substring(i + 1); // between.Y == start.Y
string[] namespaces = projectContent.GetNamespaceList(t); if (between.X < start.X) {
if (namespaces == null || namespaces.Length <= 0) { return false;
return null;
} }
return new ResolveResult(namespaces); // start is OK and between.Y <= end.Y
return between.Y < end.Y || between.X <= end.X;
} }
Expression SpecialConstructs(string expression) IMember GetCurrentMember()
{ {
if (language == SupportedLanguages.VBNet) { foreach (IProperty property in callingClass.Properties) {
// MyBase and MyClass are no expressions, only MyBase.Identifier and MyClass.Identifier if (property.BodyRegion != null && property.BodyRegion.IsInside(caretLine, caretColumn)) {
if (expression == "mybase") { return property;
return new BaseReferenceExpression(); }
} else if (expression == "myclass") { }
return new ClassReferenceExpression(); foreach (IMethod method in callingClass.Methods) {
if (method.BodyRegion != null && method.BodyRegion.IsInside(caretLine, caretColumn)) {
return method;
} }
} }
return null; return null;
} }
ResolveResult TryNamespace(IReturnType type) /// <remarks>
/// use the usings to find the correct name of a namespace
/// </remarks>
public string SearchNamespace(string name, ICompilationUnit unit)
{ {
string n = SearchNamespace(type.FullyQualifiedName, cu); /*if (projectContent.NamespaceExists(name)) {
if (n == null) { return name;
return null;
}
ArrayList content = projectContent.GetNamespaceContents(n);
ArrayList classes = new ArrayList();
for (int i = 0; i < content.Count; ++i) {
if (content[i] is IClass) {
if (inNew) {
IClass c = (IClass)content[i];
if ((c.ClassType == ClassType.Class) || (c.ClassType == ClassType.Struct)) {
classes.Add(c);
} }
} else {
classes.Add((IClass)content[i]); if (CallingClass != null) {
string callspace = this.CallingClass.Namespace;
for (int split = callspace.Length; split > 0; split = callspace.LastIndexOf('.', split - 1)) {
string fullname = callspace.Substring(0, split) + "." + name;
if (projectContent.NamespaceExists(fullname)) {
return fullname;
} }
} }
} }
string[] namespaces = projectContent.GetNamespaceList(n); */
return new ResolveResult(namespaces, classes); // TODO: look if all the stuff before is nessessary
return projectContent.SearchNamespace(name, unit, caretLine, caretColumn);
} }
bool InStatic() /// <remarks>
/// use the usings and the name of the namespace to find a class
/// </remarks>
public IClass SearchType(string name, IClass curType)
{ {
IProperty property = GetProperty(); return projectContent.SearchType(name, curType, caretLine, caretColumn);
if (property != null) {
return property.IsStatic;
}
IMethod method = GetMethod(caretLine, caretColumn);
if (method != null) {
return method.IsStatic;
} }
return false;
/// <remarks>
/// use the usings and the name of the namespace to find a class
/// </remarks>
public IClass SearchType(string name, IClass curType, ICompilationUnit unit)
{
return projectContent.SearchType(name, curType, unit, caretLine, caretColumn);
} }
#region Helper for TypeVisitor
#region SearchMethod
/// <summary>
/// Gets the list of methods on the return type that have the specified name.
/// </summary>
public ArrayList SearchMethod(IReturnType type, string memberName) public ArrayList SearchMethod(IReturnType type, string memberName)
{ {
if (type == null || type.PointerNestingLevel != 0) { if (type == null || type.PointerNestingLevel != 0) {
@ -340,22 +406,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return SearchMethod(new ArrayList(), curType, memberName); return SearchMethod(new ArrayList(), curType, memberName);
} }
bool IsSameName(string name1, string name2)
{
if (IsCaseSensitive(language)) {
return name1 == name2;
} else {
return name1.ToLower() == name2.ToLower();
}
}
ArrayList SearchMethod(ArrayList methods, IClass curType, string memberName) ArrayList SearchMethod(ArrayList methods, IClass curType, string memberName)
{ {
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType); bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType);
foreach (IMethod m in curType.Methods) { foreach (IMethod m in curType.Methods) {
if (IsSameName(m.Name, memberName) && if (IsSameName(m.Name, memberName) &&
m.MustBeShown(callingClass, showStatic, isClassInInheritanceTree) && m.MustBeShown(callingClass, true, isClassInInheritanceTree) &&
!((m.Modifiers & ModifierEnum.Override) == ModifierEnum.Override)) { !((m.Modifiers & ModifierEnum.Override) == ModifierEnum.Override)) {
methods.Add(m); methods.Add(m);
} }
@ -364,10 +421,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (baseClass != null) { if (baseClass != null) {
return SearchMethod(methods, baseClass, memberName); return SearchMethod(methods, baseClass, memberName);
} }
showStatic = false;
return methods; return methods;
} }
#endregion
#region SearchIndexer
public ArrayList SearchIndexer(IReturnType type) public ArrayList SearchIndexer(IReturnType type)
{ {
IClass curType = SearchType(type.FullyQualifiedName, null, null); IClass curType = SearchType(type.FullyQualifiedName, null, null);
@ -377,11 +435,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return new ArrayList(1); return new ArrayList(1);
} }
public ArrayList SearchIndexer(ArrayList indexer, IClass curType) ArrayList SearchIndexer(ArrayList indexer, IClass curType)
{ {
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType); bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType);
foreach (IIndexer i in curType.Indexer) { foreach (IIndexer i in curType.Indexer) {
if (i.MustBeShown(callingClass, showStatic, isClassInInheritanceTree) && !((i.Modifiers & ModifierEnum.Override) == ModifierEnum.Override)) { if (i.MustBeShown(callingClass, true, isClassInInheritanceTree) && !((i.Modifiers & ModifierEnum.Override) == ModifierEnum.Override)) {
indexer.Add(i); indexer.Add(i);
} }
} }
@ -389,131 +447,104 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (baseClass != null) { if (baseClass != null) {
return SearchIndexer(indexer, baseClass); return SearchIndexer(indexer, baseClass);
} }
showStatic = false;
return indexer; return indexer;
} }
#endregion
#region SearchMember
// no methods or indexer // no methods or indexer
public IReturnType SearchMember(IReturnType type, string memberName) public IReturnType SearchMember(IReturnType type, string memberName)
{ {
// TODO: use SearchMember from ParserService
if (type == null || memberName == null || memberName == "") { if (type == null || memberName == null || memberName == "") {
return null; return null;
} }
IClass curType = SearchType(type.FullyQualifiedName, callingClass, cu); if (type.PointerNestingLevel != 0) {
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType); return null;
}
IClass curType;
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) {
curType = SearchType("System.Array", null, null);
} else {
curType = SearchType(type.FullyQualifiedName, callingClass, cu);
}
if (curType == null)
return null;
else
return SearchMember(curType, memberName);
}
if (curType == null) { public IMember GetMember(IReturnType type, string memberName)
{
if (type == null || memberName == null || memberName == "") {
return null; return null;
} }
if (type.PointerNestingLevel != 0) { if (type.PointerNestingLevel != 0) {
return null; return null;
} }
IClass curType;
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) { if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) {
curType = SearchType("System.Array", null, null); curType = SearchType("System.Array", null, null);
} else {
curType = SearchType(type.FullyQualifiedName, callingClass, cu);
} }
if (curType.ClassType == ClassType.Enum) { if (curType == null)
foreach (IField f in curType.Fields) { return null;
if (IsSameName(f.Name, memberName) && f.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) { else
showStatic = false; return GetMember(curType, memberName);
return type; // enum members have the type of the enum
}
}
} }
if (showStatic) {
public IReturnType SearchMember(IClass curType, string memberName)
{
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType);
foreach (IClass c in curType.InnerClasses) { foreach (IClass c in curType.InnerClasses) {
if (IsSameName(c.Name, memberName) && c.IsAccessible(callingClass, isClassInInheritanceTree)) { if (IsSameName(c.Name, memberName) && c.IsAccessible(callingClass, isClassInInheritanceTree)) {
return new ReturnType(c.FullyQualifiedName); return new ReturnType(c.FullyQualifiedName);
} }
} }
} IMember member = GetMember(curType, memberName);
foreach (IProperty p in curType.Properties) { if (member == null)
if (IsSameName(p.Name, memberName) && p.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) {
showStatic = false;
return p.ReturnType;
}
}
foreach (IField f in curType.Fields) {
if (IsSameName(f.Name, memberName) && f.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) {
showStatic = false;
return f.ReturnType;
}
}
foreach (IEvent e in curType.Events) {
if (IsSameName(e.Name, memberName) && e.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) {
showStatic = false;
return e.ReturnType;
}
}
foreach (string baseType in curType.BaseTypes) {
IClass c = SearchType(baseType, curType);
if (c != null) {
IReturnType erg = SearchMember(new ReturnType(c.FullyQualifiedName), memberName);
if (erg != null) {
return erg;
}
}
}
return null; return null;
else
return member.ReturnType;
} }
bool IsInside(Point between, Point start, Point end) private IMember GetMember(IClass c, string memberName)
{ {
if (between.Y < start.Y || between.Y > end.Y) { bool isClassInInheritanceTree = false;
return false; if (callingClass != null)
} isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(c);
if (between.Y > start.Y) { foreach (IClass curType in c.ClassInheritanceTree) {
if (between.Y < end.Y) { foreach (IProperty p in curType.Properties) {
return true; if (IsSameName(p.Name, memberName) && p.MustBeShown(callingClass, true, isClassInInheritanceTree)) {
} return p;
// between.Y == end.Y
return between.X <= end.X;
} }
// between.Y == start.Y
if (between.X < start.X) {
return false;
} }
// start is OK and between.Y <= end.Y foreach (IField f in curType.Fields) {
return between.Y < end.Y || between.X <= end.X; if (IsSameName(f.Name, memberName) && f.MustBeShown(callingClass, true, isClassInInheritanceTree)) {
return f;
} }
LocalLookupVariable SearchVariable(string name)
{
ArrayList variables = (ArrayList)lookupTableVisitor.variables[IsCaseSensitive(language) ? name : name.ToLower()];
if (variables == null || variables.Count <= 0) {
return null;
} }
foreach (IEvent e in curType.Events) {
foreach (LocalLookupVariable v in variables) { if (IsSameName(e.Name, memberName) && e.MustBeShown(callingClass, true, isClassInInheritanceTree)) {
if (IsInside(new Point(caretColumn, caretLine), v.StartPos, v.EndPos)) { return e;
return v;
} }
} }
return null;
} }
IReturnType GetVariableType(LocalLookupVariable v)
{
if (v == null) {
return null; return null;
} }
IClass c = SearchType(v.TypeRef.SystemType, callingClass, cu); #endregion
if (c != null) {
return new ReturnType(c.FullyQualifiedName, v.TypeRef.RankSpecifier, v.TypeRef.PointerNestingLevel);
} else {
return new ReturnType(v.TypeRef);
}
}
#region DynamicLookup
/// <remarks> /// <remarks>
/// does the dynamic lookup for the typeName /// does the dynamic lookup for the identifier
/// </remarks> /// </remarks>
public IReturnType DynamicLookup(string typeName) public IReturnType DynamicLookup(string typeName)
{ {
// try if it exists a variable named typeName // try if it exists a variable named typeName
IReturnType variable = GetVariableType(SearchVariable(typeName)); IReturnType variable = GetVariableType(SearchVariable(typeName));
if (variable != null) { if (variable != null) {
showStatic = false;
return variable; return variable;
} }
@ -524,85 +555,29 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
// try if typeName is a method parameter // try if typeName is a method parameter
IParameter parameter = SearchMethodParameter(typeName); IParameter parameter = SearchMethodParameter(typeName);
if (parameter != null) { if (parameter != null) {
showStatic = false;
return parameter.ReturnType; return parameter.ReturnType;
} }
// check if typeName == value in set method of a property // check if typeName == value in set method of a property
if (typeName == "value") { if (typeName == "value") {
IProperty property = GetProperty(); IProperty property = callingMember as IProperty;
if (property != null && property.SetterRegion != null && property.SetterRegion.IsInside(caretLine, caretColumn)) { if (property != null && property.SetterRegion != null && property.SetterRegion.IsInside(caretLine, caretColumn)) {
showStatic = false;
return property.ReturnType; return property.ReturnType;
} }
} }
// try if there exists a nonstatic member named typeName // try if there exists a nonstatic member named typeName
showStatic = false; IReturnType t = SearchMember(callingClass, typeName);
IReturnType t = SearchMember(callingClass == null ? null : new ReturnType(callingClass.FullyQualifiedName), typeName);
if (t != null) { if (t != null) {
return t; return t;
} }
// try if there exists a static member named typeName
showStatic = true;
t = SearchMember(callingClass == null ? null : new ReturnType(callingClass.FullyQualifiedName), typeName);
if (t != null) {
showStatic = false;
return t;
}
// try if there exists a static member in outer classes named typeName // try if there exists a static member in outer classes named typeName
List<IClass> classes = cu.GetOuterClasses(caretLine, caretColumn); List<IClass> classes = cu.GetOuterClasses(caretLine, caretColumn);
foreach (IClass c in classes) { foreach (IClass c in classes) {
t = SearchMember(callingClass == null ? null : new ReturnType(c.FullyQualifiedName), typeName); IMember member = GetMember(c, typeName);
if (t != null) { if (member != null && member.IsStatic) {
showStatic = false; return member.ReturnType;
return t;
}
}
// Alex: look in namespaces
// Alex: look inside namespaces
string[] innamespaces = projectContent.GetNamespaceList("");
foreach (string ns in innamespaces) {
ArrayList objs = projectContent.GetNamespaceContents(ns);
if (objs == null) continue;
foreach (object o in objs) {
if (o is IClass) {
IClass oc=(IClass)o;
if (IsSameName(oc.Name, typeName) || IsSameName(oc.FullyQualifiedName, typeName)) {
//Debug.WriteLine(((IClass)o).Name);
/// now we can set completion data
objs.Clear();
objs = null;
return new ReturnType(oc.FullyQualifiedName);
}
}
}
if (objs == null) {
break;
}
}
innamespaces = null;
return null;
}
IProperty GetProperty()
{
foreach (IProperty property in callingClass.Properties) {
if (property.BodyRegion != null && property.BodyRegion.IsInside(caretLine, caretColumn)) {
return property;
}
}
return null;
}
IMethod GetMethod(int caretLine, int caretColumn)
{
foreach (IMethod method in callingClass.Methods) {
if (method.BodyRegion != null && method.BodyRegion.IsInside(caretLine, caretColumn)) {
return method;
} }
} }
return null; return null;
@ -610,7 +585,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
IParameter SearchMethodParameter(string parameter) IParameter SearchMethodParameter(string parameter)
{ {
IMethod method = GetMethod(caretLine, caretColumn); IMethod method = callingMember as IMethod;
if (method == null) { if (method == null) {
return null; return null;
} }
@ -622,116 +597,37 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return null; return null;
} }
/// <remarks> IReturnType GetVariableType(LocalLookupVariable v)
/// use the usings to find the correct name of a namespace
/// </remarks>
public string SearchNamespace(string name, ICompilationUnit unit)
{
if (projectContent.NamespaceExists(name)) {
return name;
}
if (CallingClass != null) {
string callspace = this.CallingClass.Namespace;
for (int split = callspace.Length; split > 0; split = callspace.LastIndexOf('.', split - 1)) {
string fullname = callspace.Substring(0, split) + "." + name;
if (projectContent.NamespaceExists(fullname)) {
return fullname;
}
}
}
// TODO: look if all the stuff before is nessessary
return projectContent.SearchNamespace(name, unit, caretLine, caretColumn);
}
/// <remarks>
/// use the usings and the name of the namespace to find a class
/// </remarks>
public IClass SearchType(string name, IClass curType)
{
return projectContent.SearchType(name, curType, caretLine, caretColumn);
}
/// <remarks>
/// use the usings and the name of the namespace to find a class
/// </remarks>
public IClass SearchType(string name, IClass curType, ICompilationUnit unit)
{
return projectContent.SearchType(name, curType, unit, caretLine, caretColumn);
}
public FilePosition SearchDefinition(string expression,
int caretLineNumber,
int caretColumn,
string fileName)
{ {
this.caretLine = caretLineNumber; if (v == null) {
this.caretColumn = caretColumn;
ICSharpCode.NRefactory.Parser.IParser p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(language, new System.IO.StringReader(expression));
Expression expr = p.ParseExpression();
ParseInformation parseInfo = ParserService.GetParseInformation(fileName);
if (parseInfo == null) {
return null; return null;
} }
NRefactoryASTConvertVisitor cSharpVisitor = new NRefactoryASTConvertVisitor(parseInfo.MostRecentCompilationUnit != null ? parseInfo.MostRecentCompilationUnit.ProjectContent : null); IClass c = SearchType(v.TypeRef.SystemType, callingClass, cu);
ICSharpCode.NRefactory.Parser.AST.CompilationUnit fileCompilationUnit = parseInfo.MostRecentCompilationUnit.Tag as ICSharpCode.NRefactory.Parser.AST.CompilationUnit; if (c != null) {
cu = (ICompilationUnit)cSharpVisitor.Visit(fileCompilationUnit, null); return new ReturnType(c.FullyQualifiedName, v.TypeRef.RankSpecifier, v.TypeRef.PointerNestingLevel);
if (cu != null) { } else {
callingClass = cu.GetInnermostClass(caretLine, caretColumn); return new ReturnType(v.TypeRef);
}
if (callingClass == null) {
return null;
} }
if (expr is IdentifierExpression) {
lookupTableVisitor = new LookupTableVisitor();
lookupTableVisitor.Visit(fileCompilationUnit, null);
// try if it exists a variable named typeName
LocalLookupVariable variable = SearchVariable(expression);
if (variable != null) {
return new FilePosition(fileName, variable.StartPos);
} }
// try if typeName is a method parameter LocalLookupVariable SearchVariable(string name)
IParameter parameter = SearchMethodParameter(expression); {
if (parameter != null) { ArrayList variables = (ArrayList)lookupTableVisitor.variables[IsCaseSensitive(language) ? name : name.ToLower()];
return new FilePosition(fileName, new Point(parameter.Region.BeginColumn, parameter.Region.BeginLine)); if (variables == null || variables.Count <= 0) {
}
return null; return null;
} }
string target = expression.Substring(0, expression.LastIndexOf('.')); foreach (LocalLookupVariable v in variables) {
string member = expression.Substring(expression.LastIndexOf('.') + 1); if (IsInside(new Point(caretColumn, caretLine), v.StartPos, v.EndPos)) {
p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(language, new System.IO.StringReader(target)); return v;
Expression targetExpr = p.ParseExpression();
TypeVisitor typeVisitor = new TypeVisitor(this);
IReturnType type = expr.AcceptVisitor(typeVisitor, null) as IReturnType;
if (type == null || type.FullyQualifiedName == "" || type.PointerNestingLevel != 0) {
return null;
}
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) {
type = new ReturnType("System.Array");
}
IClass returnClass = SearchType(type.FullyQualifiedName, callingClass, cu);
if (returnClass == null) {
string n = SearchNamespace(type.FullyQualifiedName, cu);
if (n == null) {
return null;
}
returnClass = SearchType(n + '.' + member, callingClass, cu);
if (returnClass != null) {
return new FilePosition(fileName, new Point(returnClass.Region.BeginColumn, returnClass.Region.BeginLine));
} }
return null;
} }
return null; return null;
} }
#endregion
#endregion
/*
public ArrayList NewCompletion(int caretLine, int caretColumn, string fileName) public ArrayList NewCompletion(int caretLine, int caretColumn, string fileName)
{ {
if (!IsCaseSensitive(language)) { if (!IsCaseSensitive(language)) {
@ -764,7 +660,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
} }
return result; return result;
} }*/
public ArrayList CtrlSpace(int caretLine, int caretColumn, string fileName) public ArrayList CtrlSpace(int caretLine, int caretColumn, string fileName)
{ {
@ -785,14 +681,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (cu != null) { if (cu != null) {
callingClass = cu.GetInnermostClass(caretLine, caretColumn); callingClass = cu.GetInnermostClass(caretLine, caretColumn);
if (callingClass != null) { if (callingClass != null) {
IMethod method = GetMethod(caretLine, caretColumn); IMethod method = callingMember as IMethod;
if (method != null) { if (method != null) {
foreach (IParameter p in method.Parameters) { foreach (IParameter p in method.Parameters) {
result.Add(new Field(new ReturnType(p.ReturnType.Name, p.ReturnType.ArrayDimensions, p.ReturnType.PointerNestingLevel), p.Name, Modifier.None, method.Region, callingClass)); result.Add(new Field(new ReturnType(p.ReturnType.Name, p.ReturnType.ArrayDimensions, p.ReturnType.PointerNestingLevel), p.Name, Modifier.None, method.Region, callingClass));
} }
} }
result.AddRange(projectContent.GetNamespaceContents(callingClass.Namespace)); result.AddRange(projectContent.GetNamespaceContents(callingClass.Namespace));
bool inStatic = InStatic(); bool inStatic = true;
if (callingMember != null)
inStatic = callingMember.IsStatic;
result.AddRange(callingClass.GetAccessibleMembers(callingClass, inStatic).ToArray()); result.AddRange(callingClass.GetAccessibleMembers(callingClass, inStatic).ToArray());
if (inStatic == false) { if (inStatic == false) {
result.AddRange(callingClass.GetAccessibleMembers(callingClass, !inStatic).ToArray()); result.AddRange(callingClass.GetAccessibleMembers(callingClass, !inStatic).ToArray());

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

@ -43,36 +43,37 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
public override object Visit(InvocationExpression invocationExpression, object data) public override object Visit(InvocationExpression invocationExpression, object data)
{
IMethod m = GetMethod(invocationExpression, data);
if (m == null)
return null;
else
return m.ReturnType;
}
public IMethod GetMethod(InvocationExpression invocationExpression, object data)
{ {
if (invocationExpression.TargetObject is FieldReferenceExpression) { if (invocationExpression.TargetObject is FieldReferenceExpression) {
FieldReferenceExpression field = (FieldReferenceExpression)invocationExpression.TargetObject; FieldReferenceExpression field = (FieldReferenceExpression)invocationExpression.TargetObject;
IReturnType type = field.TargetObject.AcceptVisitor(this, data) as IReturnType; IReturnType type = field.TargetObject.AcceptVisitor(this, data) as IReturnType;
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) {
type = new ReturnType("System.Array");
}
ArrayList methods = resolver.SearchMethod(type, field.FieldName); ArrayList methods = resolver.SearchMethod(type, field.FieldName);
resolver.ShowStatic = false;
if (methods.Count <= 0) { if (methods.Count <= 0) {
return null; return null;
} }
// TODO: Find the right method // TODO: Find the right method
return ((IMethod)methods[0]).ReturnType; return (IMethod)methods[0];
} else if (invocationExpression.TargetObject is IdentifierExpression) { } else if (invocationExpression.TargetObject is IdentifierExpression) {
string id = ((IdentifierExpression)invocationExpression.TargetObject).Identifier; string id = ((IdentifierExpression)invocationExpression.TargetObject).Identifier;
if (resolver.CallingClass == null) { if (resolver.CallingClass == null) {
return null; return null;
} }
IReturnType type = new ReturnType(resolver.CallingClass.FullyQualifiedName); IReturnType type = new ReturnType(resolver.CallingClass.FullyQualifiedName);
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) {
type = new ReturnType("System.Array");
}
ArrayList methods = resolver.SearchMethod(type, id); ArrayList methods = resolver.SearchMethod(type, id);
resolver.ShowStatic = false;
if (methods.Count <= 0) { if (methods.Count <= 0) {
return null; return null;
} }
// TODO: Find the right method // TODO: Find the right method
return ((IMethod)methods[0]).ReturnType; return (IMethod)methods[0];
} }
// invocationExpression is delegate call // invocationExpression is delegate call
IReturnType t = invocationExpression.AcceptChildren(this, data) as IReturnType; IReturnType t = invocationExpression.AcceptChildren(this, data) as IReturnType;
@ -85,7 +86,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (methods.Count <= 0) { if (methods.Count <= 0) {
return null; return null;
} }
return ((IMethod)methods[0]).ReturnType; return (IMethod)methods[0];
} }
return null; return null;
} }
@ -98,7 +99,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
// int. generates a FieldreferenceExpression with TargetObject TypeReferenceExpression and no FieldName // int. generates a FieldreferenceExpression with TargetObject TypeReferenceExpression and no FieldName
if (fieldReferenceExpression.FieldName == null || fieldReferenceExpression.FieldName == "") { if (fieldReferenceExpression.FieldName == null || fieldReferenceExpression.FieldName == "") {
if (fieldReferenceExpression.TargetObject is TypeReferenceExpression) { if (fieldReferenceExpression.TargetObject is TypeReferenceExpression) {
resolver.ShowStatic = true;
return new ReturnType(((TypeReferenceExpression)fieldReferenceExpression.TargetObject).TypeReference); return new ReturnType(((TypeReferenceExpression)fieldReferenceExpression.TargetObject).TypeReference);
} }
} }
@ -112,7 +112,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
IClass c = resolver.SearchType(name + "." + fieldReferenceExpression.FieldName, resolver.CallingClass, resolver.CompilationUnit); IClass c = resolver.SearchType(name + "." + fieldReferenceExpression.FieldName, resolver.CallingClass, resolver.CompilationUnit);
if (c != null) { if (c != null) {
resolver.ShowStatic = true;
return new ReturnType(c.FullyQualifiedName); return new ReturnType(c.FullyQualifiedName);
} }
return null; return null;
@ -147,7 +146,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
IClass c = resolver.SearchType(identifierExpression.Identifier, resolver.CallingClass, resolver.CompilationUnit); IClass c = resolver.SearchType(identifierExpression.Identifier, resolver.CallingClass, resolver.CompilationUnit);
if (c != null) { if (c != null) {
resolver.ShowStatic = true;
return new ReturnType(c.FullyQualifiedName); return new ReturnType(c.FullyQualifiedName);
} }
return resolver.DynamicLookup(identifierExpression.Identifier); return resolver.DynamicLookup(identifierExpression.Identifier);

295
src/Main/Base/Project/Src/Dom/ResolveResult.cs

@ -0,0 +1,295 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krueger" email="mike@icsharpcode.net"/>
// <version value="$version"/>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom
{
#region ResolveResult
/// <summary>
/// The base class of all resolve results.
/// This class is used whenever an expression is not one of the special expressions
/// (having their own ResolveResult class).
/// The ResolveResult specified the location where Resolve was called (Class+Member)
/// and the type of the resolved expression.
/// </summary>
public class ResolveResult
{
IClass callingClass;
IMember callingMember;
IReturnType resolvedType;
public ResolveResult(IClass callingClass, IMember callingMember, IReturnType resolvedType)
{
// if (callingMember != null && callingMember.DeclaringType != callingClass)
// throw new ArgumentException("callingMember.DeclaringType must be equal to callingClass");
this.callingClass = callingClass;
this.callingMember = callingMember;
this.resolvedType = resolvedType;
}
/// <summary>
/// Gets the class that contained the expression used to get this ResolveResult.
/// Can be null when the class is unknown.
/// </summary>
public IClass CallingClass {
get {
return callingClass;
}
}
/// <summary>
/// Gets the member (method or property in <see cref="CallingClass"/>) that contained the
/// expression used to get this ResolveResult.
/// Can be null when the expression was not inside a member or the member is unknown.
/// </summary>
public IMember CallingMember {
get {
return callingMember;
}
}
/// <summary>
/// Gets the type of the resolved expression.
/// Can be null when the type cannot be represented by a IReturnType (e.g. when the
/// expression was a namespace name).
/// </summary>
public IReturnType ResolvedType {
get {
return resolvedType;
}
}
public virtual ArrayList GetCompletionData(IProjectContent projectContent)
{
if (resolvedType == null)
return null;
IClass c = projectContent.GetClass(resolvedType.FullyQualifiedName);
if (c == null)
return null;
return c.GetAccessibleMembers(callingClass, false);
}
}
#endregion
#region LocalResolveResult
/// <summary>
/// The LocalResolveResult is used when an expression was a simple local variable
/// or parameter.
/// </summary>
/// <remarks>
/// For fields in the current class, a MemberResolveResult is used, so "e" is not always
/// a LocalResolveResult.
/// </remarks>
public class LocalResolveResult : ResolveResult
{
IField field;
bool isParameter;
public LocalResolveResult(IClass callingClass, IMember callingMember, IField field, bool isParameter)
: base(callingClass, callingMember, field.ReturnType)
{
if (callingMember == null)
throw new ArgumentNullException("callingMember");
if (field == null)
throw new ArgumentNullException("field");
this.field = field;
this.isParameter = isParameter;
}
/// <summary>
/// Gets the field representing the local variable.
/// </summary>
public IField Field {
get {
return field;
}
}
/// <summary>
/// Gets if the variable is a parameter (true) or a local variable (false).
/// </summary>
public bool IsParameter {
get {
return isParameter;
}
}
}
#endregion
#region NamespaceResolveResult
/// <summary>
/// The NamespaceResolveResult is used when an expression was the name of a namespace.
/// <see cref="ResolveResult.ResolvedType"/> is always null on a NamespaceReturnType.
/// </summary>
/// <example>
/// Example expressions:
/// "System"
/// "System.Windows.Forms"
/// "using Win = System.Windows; Win.Forms"
/// </example>
public class NamespaceResolveResult : ResolveResult
{
string name;
public NamespaceResolveResult(IClass callingClass, IMember callingMember, string name)
: base(callingClass, callingMember, null)
{
if (name == null)
throw new ArgumentNullException("name");
this.name = name;
}
/// <summary>
/// Gets the name of the namespace.
/// </summary>
public string Name {
get {
return name;
}
}
public override ArrayList GetCompletionData(IProjectContent projectContent)
{
return projectContent.GetNamespaceContents(name);
}
}
#endregion
#region TypeResolveResult
/// <summary>
/// The TypeResolveResult is used when an expression was the name of a type.
/// This resolve result makes code completion show the static members instead
/// of the instance members.
/// </summary>
/// <example>
/// Example expressions:
/// "System.EventArgs"
/// "using System; EventArgs"
/// </example>
public class TypeResolveResult : ResolveResult
{
IClass resolvedClass;
public TypeResolveResult(IClass callingClass, IMember callingMember, IReturnType resolvedType, IClass resolvedClass)
: base(callingClass, callingMember, resolvedType)
{
this.resolvedClass = resolvedClass;
}
/// <summary>
/// Gets the class corresponding to the resolved type.
/// </summary>
public IClass ResolvedClass {
get {
return resolvedClass;
}
}
public override ArrayList GetCompletionData(IProjectContent projectContent)
{
if (resolvedClass == null)
return null;
else
return resolvedClass.GetAccessibleMembers(this.CallingClass, true);
}
}
#endregion
#region MemberResolveResult
/// <summary>
/// The TypeResolveResult is used when an expression was a member
/// (field, property, event or method call).
/// </summary>
/// <example>
/// Example expressions:
/// "(any expression).fieldName"
/// "(any expression).eventName"
/// "(any expression).propertyName"
/// "(any expression).methodName(arguments)" (methods only when method parameters are part of expression)
/// "using System; EventArgs.Empty"
/// "fieldName" (when fieldName is a field in the current class)
/// "new System.Windows.Forms.Button()" (constructors are also methods)
/// "SomeMethod()" (when SomeMethod is a method in the current class)
/// "System.Console.WriteLine(text)"
/// </example>
public class MemberResolveResult : ResolveResult
{
IMember resolvedMember;
public MemberResolveResult(IClass callingClass, IMember callingMember, IMember resolvedMember)
: base(callingClass, callingMember, resolvedMember.ReturnType)
{
if (resolvedMember == null)
throw new ArgumentNullException("resolvedMember");
this.resolvedMember = resolvedMember;
}
/// <summary>
/// Gets the member that was resolved.
/// </summary>
public IMember ResolvedMember {
get {
return resolvedMember;
}
}
}
#endregion
#region MethodResolveResult
/// <summary>
/// The MethodResolveResult is used when an expression was the name of a method,
/// but there were no parameters specified so the exact overload could not be found.
/// <see cref="ResolveResult.ResolvedType"/> is always null on a MethodReturnType.
/// </summary>
/// <example>
/// Example expressions:
/// "System.Console.WriteLine"
/// "SomeMethod" (when SomeMethod is a method in the current class)
/// </example>
public class MethodResolveResult : ResolveResult
{
string name;
IClass containingClass;
public MethodResolveResult(IClass callingClass, IMember callingMember, IClass containingClass, string name)
: base(callingClass, callingMember, null)
{
if (containingClass == null)
throw new ArgumentNullException("containingClass");
if (name == null)
throw new ArgumentNullException("name");
this.containingClass = containingClass;
this.name = name;
}
/// <summary>
/// Gets the name of the method.
/// </summary>
public string Name {
get {
return name;
}
}
/// <summary>
/// Gets the class on that contains the method.
/// </summary>
public IClass ContainingClass {
get {
return containingClass;
}
}
}
#endregion
}

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

@ -150,6 +150,8 @@ namespace ICSharpCode.Core
} }
} }
} catch (Exception e) { } catch (Exception e) {
Console.Beep();
Console.WriteLine();
Console.WriteLine(e); Console.WriteLine(e);
} }
Thread.Sleep(2000); Thread.Sleep(2000);

3
src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionDataProvider.cs

@ -212,8 +212,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
insertedEventElements.Clear(); insertedEventElements.Clear();
if (results != null) { if (results != null) {
AddResolveResults(results.Namespaces); AddResolveResults(results.GetCompletionData(ParserService.CurrentProjectContent));
AddResolveResults(results.Members);
} }
} }
} }

1
src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CommentCompletionDataProvider.cs

@ -39,6 +39,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
new string[] {"item", "A list item"}, new string[] {"item", "A list item"},
new string[] {"term", "A term in a list"}, new string[] {"term", "A term in a list"},
new string[] {"description", "A description to a term in a list"}, new string[] {"description", "A description to a term in a list"},
new string[] {"para", "A text paragraph"},
new string[] {"param name=\"\"", "A description for a parameter"}, new string[] {"param name=\"\"", "A description for a parameter"},
new string[] {"paramref name=\"\"", "A reference to a parameter"}, new string[] {"paramref name=\"\"", "A reference to a parameter"},
new string[] {"permission cref=\"\"", ""}, new string[] {"permission cref=\"\"", ""},

3
src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/IndexerInsightDataProvider.cs

@ -55,7 +55,9 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
this.textArea = textArea; this.textArea = textArea;
initialOffset = textArea.Caret.Offset; initialOffset = textArea.Caret.Offset;
// TODO: Change this for the new resolver, or better merge IndexerInsight and MethodInsight.
/*
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName); IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName);
string word = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset(textArea, textArea.Caret.Offset) : expressionFinder.FindExpression(textArea.Document.TextContent, textArea.Caret.Offset - 1); string word = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset(textArea, textArea.Caret.Offset) : expressionFinder.FindExpression(textArea.Document.TextContent, textArea.Caret.Offset - 1);
@ -85,6 +87,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
// } // }
// } // }
} }
*/
} }
public bool CaretOffsetChanged() public bool CaretOffsetChanged()

96
src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs

@ -59,90 +59,48 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
this.textArea = textArea; this.textArea = textArea;
initialOffset = textArea.Caret.Offset; initialOffset = textArea.Caret.Offset;
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName); IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName);
string word = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset(textArea, textArea.Caret.Offset) : expressionFinder.FindExpression(textArea.Document.TextContent, textArea.Caret.Offset - 1); string word = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset(textArea, textArea.Caret.Offset) : expressionFinder.FindExpression(textArea.Document.TextContent, textArea.Caret.Offset - 1);
word = word.Trim();
string methodObject = word;
string methodName = null;
int idx = methodObject.LastIndexOf('.');
if (idx >= 0) {
methodName = methodObject.Substring(idx + 1);
methodObject = methodObject.Substring(0, idx);
} else {
methodObject = fileName.EndsWith("vb") ? "Me" : "this";
methodName = word;
}
if (methodName.Length == 0 || methodObject.Length == 0) {
return;
}
// the parser works with 1 based coordinates // the parser works with 1 based coordinates
caretLineNumber = document.GetLineNumberForOffset(textArea.Caret.Offset) + 1; caretLineNumber = document.GetLineNumberForOffset(textArea.Caret.Offset) + 1;
caretColumn = textArea.Caret.Offset - document.GetLineSegment(caretLineNumber).Offset + 1; caretColumn = textArea.Caret.Offset - document.GetLineSegment(caretLineNumber).Offset + 1;
string[] words = word.Split(' '); bool constructorInsight = false;
bool contructorInsight = false; if (word.ToLower().StartsWith("new ")) {
if (words.Length > 1) { constructorInsight = true;
contructorInsight = words[words.Length - 2] == "new"; word = word.Substring(4);
if (contructorInsight) {
methodObject = words[words.Length - 1];
}
}
ResolveResult results = ParserService.Resolve(methodObject, caretLineNumber, caretColumn, fileName, document.TextContent);
if (results != null && results.Type != null) {
if (contructorInsight) {
AddConstructors(results.Type);
} else {
foreach (IClass c in results.Type.ClassInheritanceTree) {
AddMethods(c, methodName, false);
}
}
}
}
Hashtable includedMethods = new Hashtable();
bool IsAlreadyIncluded(IMethod newMethod)
{
foreach (IMethod method in methods) {
if (method.Name == newMethod.Name) {
if (newMethod.Parameters.Count != method.Parameters.Count) {
return false;
}
for (int i = 0; i < newMethod.Parameters.Count; ++i) {
if (newMethod.Parameters[i].ReturnType != method.Parameters[i].ReturnType) {
return false;
}
} }
ResolveResult results = ParserService.Resolve(word, caretLineNumber, caretColumn, fileName, document.TextContent);
// // take out old method, when it isn't documented. if (constructorInsight) {
// if (method.Documentation == null || method.Documentation.Length == 0) { TypeResolveResult result = results as TypeResolveResult;
// methods.Remove(method); if (result == null)
// return false; return;
// } IClass c = result.ResolvedClass;
return true; bool canViewProtected = c.IsTypeInInheritanceTree(result.CallingClass);
foreach (IMethod method in c.Methods) {
if (method.IsConstructor) {
if (method.IsAccessible(result.CallingClass, canViewProtected)) {
methods.Add(method);
} }
} }
return false;
} }
} else {
void AddConstructors(IClass c) MethodResolveResult result = results as MethodResolveResult;
{ if (result == null)
foreach (IMethod method in c.Methods) { return;
if (method.IsConstructor && !method.IsStatic) { IClass c = result.ContainingClass;
bool canViewProtected = c.IsTypeInInheritanceTree(result.CallingClass);
foreach (IClass curType in c.ClassInheritanceTree) {
foreach (IMethod method in curType.Methods) {
if (method.Name == result.Name) {
if (method.IsAccessible(result.CallingClass, canViewProtected)) {
// TODO: exclude methods that were overridden
methods.Add(method); methods.Add(method);
} }
} }
} }
void AddMethods(IClass c, string methodName, bool discardPrivate)
{
foreach (IMethod method in c.Methods) {
if (!(method.IsPrivate && discardPrivate) &&
method.Name == methodName &&
!IsAlreadyIncluded(method)) {
methods.Add(method);
} }
} }
} }

16
src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextAreaControl.cs

@ -305,7 +305,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
} }
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e); LogException(e);
} }
goto case '.'; goto case '.';
case '<': case '<':
@ -317,7 +317,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
} }
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e); LogException(e);
} }
return false; return false;
case '(': case '(':
@ -335,7 +335,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
} }
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e); LogException(e);
} }
return false; return false;
case '[': case '[':
@ -355,7 +355,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e); LogException(e);
} }
return false; return false;
case '.': case '.':
@ -369,7 +369,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
// TextAreaPainter.IHaveTheFocusLock = false; // TextAreaPainter.IHaveTheFocusLock = false;
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e); LogException(e);
} }
return false; return false;
//// Alex: reparse file on ; - end of statement //// Alex: reparse file on ; - end of statement
@ -383,6 +383,12 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
return false; return false;
} }
private void LogException(Exception ex)
{
Console.WriteLine();
Console.WriteLine("EXCEPTION: " + ex);
Console.Beep(); // notify user
}
public string GetWordBeforeCaret() public string GetWordBeforeCaret()
{ {

4
src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs

@ -392,8 +392,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
parseInfo = ParserService.GetParseInformation(fileName); parseInfo = ParserService.GetParseInformation(fileName);
} }
textAreaControl.Document.FoldingManager.UpdateFoldings(fileName, parseInfo); textAreaControl.Document.FoldingManager.UpdateFoldings(fileName, parseInfo);
//// Alex free parsings - not sure if better place is in UpdateFoldings asap
parseInfo=null;
} }
} }
@ -401,8 +399,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{ {
if (textAreaControl.TextEditorProperties.EnableFolding) { if (textAreaControl.TextEditorProperties.EnableFolding) {
textAreaControl.Document.FoldingManager.UpdateFoldings(TitleName, parseInfo); textAreaControl.Document.FoldingManager.UpdateFoldings(TitleName, parseInfo);
//// Alex free parsings
parseInfo=null;
textAreaControl.ActiveTextAreaControl.TextArea.Invoke(new VoidDelegate(textAreaControl.ActiveTextAreaControl.TextArea.Refresh), new object[] { textAreaControl.ActiveTextAreaControl.TextArea.FoldMargin}); textAreaControl.ActiveTextAreaControl.TextArea.Invoke(new VoidDelegate(textAreaControl.ActiveTextAreaControl.TextArea.Refresh), new object[] { textAreaControl.ActiveTextAreaControl.TextArea.FoldMargin});
} }
} }

Loading…
Cancel
Save