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 @@ @@ -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>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -618,6 +618,7 @@ @@ -618,6 +618,7 @@
<Compile Include="Src\Dom\XmlDoc.cs" />
<Compile Include="Src\Services\ParserService\ProjectContentRegistry.cs" />
<Compile Include="Src\Dom\NRefactoryResolver\FilePosition.cs" />
<Compile Include="Src\Dom\ResolveResult.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj">

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

@ -14,110 +14,9 @@ using ICSharpCode.Core; @@ -14,110 +14,9 @@ using ICSharpCode.Core;
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 {
string[] LexerTags {
//// Alex - need to have get accessor too
get;
set;
}
@ -132,6 +31,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -132,6 +31,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// extension.
/// </summary>
bool CanParse(string fileName);
/// <summary>
/// Gets if the parser can parse the specified project.
/// 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 @@ -362,7 +362,9 @@ namespace ICSharpCode.SharpDevelop.Dom
return members;
}
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(this);
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(this);
if (showStatic) {
foreach (IClass c in InnerClasses) {

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

@ -303,7 +303,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -303,7 +303,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
for (int i = 0; i < fieldDeclaration.Fields.Count; ++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));
if (c.ClassType == ClassType.Enum) {
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 @@ -21,12 +21,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
ICompilationUnit cu;
IClass callingClass;
IMember callingMember;
ICSharpCode.NRefactory.Parser.LookupTableVisitor lookupTableVisitor;
IProjectContent projectContent = null;
bool showStatic = false;
bool inNew = false;
bool caseSensitive = true;
SupportedLanguages language = SupportedLanguages.CSharp;
@ -60,16 +58,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -60,16 +58,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
}
public bool ShowStatic {
get {
return showStatic;
}
set {
showStatic = value;
}
}
public NRefactoryResolver(SupportedLanguages language)
{
this.language = language;
@ -103,21 +91,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -103,21 +91,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
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.caretColumn = caretColumn;
@ -156,40 +129,147 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -156,40 +129,147 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (cu != null) {
callingClass = cu.GetInnermostClass(caretLine, caretColumn);
}
callingMember = GetCurrentMember();
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;
if (type == null || type.FullyQualifiedName == "" || type.PointerNestingLevel != 0) {
return null;
}
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) {
type = new ReturnType("System.Array");
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0)
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);
if (returnClass == null) {
return TryNamespace(type);
if (returnClass != null && returnClass.FullyQualifiedName != type.FullyQualifiedName)
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) {
return new ResolveResult(returnClass, returnClass.GetAccessibleTypes(callingClass));
IClass curType;
if (type.ArrayDimensions != null && type.ArrayDimensions.Length > 0) {
curType = SearchType("System.Array", null, null);
} else {
ArrayList result = returnClass.GetAccessibleMembers(callingClass, showStatic);
if (!showStatic && language == SupportedLanguages.VBNet) {
result.AddRange(returnClass.GetAccessibleMembers(callingClass, true).ToArray());
curType = SearchType(type.FullyQualifiedName, null, null);
if (curType == null) {
return null;
}
return new ResolveResult(returnClass, result);
}
return ResolveMethod(curType, identifier);
}
bool IsNumber(string expression)
ResolveResult ResolveMethod(IClass c, string identifier)
{
try {
int.Parse(expression);
return true;
} catch (Exception) {
return false;
foreach (IClass curType in c.ClassInheritanceTree) {
foreach (IMethod method in c.Methods) {
if (IsSameName(identifier, method.Name))
return new MethodResolveResult(callingClass, callingMember, c, identifier);
}
}
return null;
}
#endregion
Expression WithResolve()
{
@ -208,121 +288,107 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -208,121 +288,107 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return expr;
}
string GetUsingString()
{
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 SpecialConstructs(string expression)
{
// 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) {
if (!(Char.IsLetterOrDigit(expression[i]) || expression[i] == '_' || expression[i] == '.')) {
break;
}
if (language == SupportedLanguages.VBNet) {
// MyBase and MyClass are no expressions, only MyBase.Identifier and MyClass.Identifier
if (expression == "mybase") {
return new BaseReferenceExpression();
} else if (expression == "myclass") {
return new ClassReferenceExpression();
}
// 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 new ResolveResult(namespaces);
}
ResolveResult UsingResolve(string expression)
bool IsSameName(string name1, string name2)
{
if (language == SupportedLanguages.VBNet) {
return ImportsResolve(expression);
if (IsCaseSensitive(language)) {
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) {
if (!(Char.IsLetterOrDigit(expression[i]) || expression[i] == '_' || expression[i] == '.')) {
break;
bool IsInside(Point between, Point start, Point end)
{
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
if (i == expression.Length - 1) {
return null;
// between.Y == end.Y
return between.X <= end.X;
}
string t = expression.Substring(i + 1);
string[] namespaces = projectContent.GetNamespaceList(t);
if (namespaces == null || namespaces.Length <= 0) {
return null;
// between.Y == start.Y
if (between.X < start.X) {
return false;
}
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) {
// MyBase and MyClass are no expressions, only MyBase.Identifier and MyClass.Identifier
if (expression == "mybase") {
return new BaseReferenceExpression();
} else if (expression == "myclass") {
return new ClassReferenceExpression();
foreach (IProperty property in callingClass.Properties) {
if (property.BodyRegion != null && property.BodyRegion.IsInside(caretLine, caretColumn)) {
return property;
}
}
foreach (IMethod method in callingClass.Methods) {
if (method.BodyRegion != null && method.BodyRegion.IsInside(caretLine, caretColumn)) {
return method;
}
}
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 (n == null) {
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);
/*if (projectContent.NamespaceExists(name)) {
return name;
}
} 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();
if (property != null) {
return property.IsStatic;
}
IMethod method = GetMethod(caretLine, caretColumn);
if (method != null) {
return method.IsStatic;
return projectContent.SearchType(name, curType, caretLine, caretColumn);
}
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)
{
if (type == null || type.PointerNestingLevel != 0) {
@ -340,22 +406,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -340,22 +406,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
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)
{
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType);
foreach (IMethod m in curType.Methods) {
if (IsSameName(m.Name, memberName) &&
m.MustBeShown(callingClass, showStatic, isClassInInheritanceTree) &&
m.MustBeShown(callingClass, true, isClassInInheritanceTree) &&
!((m.Modifiers & ModifierEnum.Override) == ModifierEnum.Override)) {
methods.Add(m);
}
@ -364,10 +421,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -364,10 +421,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (baseClass != null) {
return SearchMethod(methods, baseClass, memberName);
}
showStatic = false;
return methods;
}
#endregion
#region SearchIndexer
public ArrayList SearchIndexer(IReturnType type)
{
IClass curType = SearchType(type.FullyQualifiedName, null, null);
@ -377,11 +435,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -377,11 +435,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return new ArrayList(1);
}
public ArrayList SearchIndexer(ArrayList indexer, IClass curType)
ArrayList SearchIndexer(ArrayList indexer, IClass curType)
{
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType);
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);
}
}
@ -389,131 +447,104 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -389,131 +447,104 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (baseClass != null) {
return SearchIndexer(indexer, baseClass);
}
showStatic = false;
return indexer;
}
#endregion
#region SearchMember
// no methods or indexer
public IReturnType SearchMember(IReturnType type, string memberName)
{
// TODO: use SearchMember from ParserService
if (type == null || memberName == null || memberName == "") {
return null;
}
IClass curType = SearchType(type.FullyQualifiedName, callingClass, cu);
bool isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(curType);
if (type.PointerNestingLevel != 0) {
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;
}
if (type.PointerNestingLevel != 0) {
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.ClassType == ClassType.Enum) {
foreach (IField f in curType.Fields) {
if (IsSameName(f.Name, memberName) && f.MustBeShown(callingClass, showStatic, isClassInInheritanceTree)) {
showStatic = false;
return type; // enum members have the type of the enum
}
}
if (curType == null)
return null;
else
return GetMember(curType, memberName);
}
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) {
if (IsSameName(c.Name, memberName) && c.IsAccessible(callingClass, isClassInInheritanceTree)) {
return new ReturnType(c.FullyQualifiedName);
}
}
}
foreach (IProperty p in curType.Properties) {
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;
}
}
}
IMember member = GetMember(curType, memberName);
if (member == 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) {
return false;
}
if (between.Y > start.Y) {
if (between.Y < end.Y) {
return true;
}
// between.Y == end.Y
return between.X <= end.X;
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(c);
foreach (IClass curType in c.ClassInheritanceTree) {
foreach (IProperty p in curType.Properties) {
if (IsSameName(p.Name, memberName) && p.MustBeShown(callingClass, true, isClassInInheritanceTree)) {
return p;
}
// between.Y == start.Y
if (between.X < start.X) {
return false;
}
// start is OK and between.Y <= end.Y
return between.Y < end.Y || between.X <= end.X;
foreach (IField f in curType.Fields) {
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 (LocalLookupVariable v in variables) {
if (IsInside(new Point(caretColumn, caretLine), v.StartPos, v.EndPos)) {
return v;
foreach (IEvent e in curType.Events) {
if (IsSameName(e.Name, memberName) && e.MustBeShown(callingClass, true, isClassInInheritanceTree)) {
return e;
}
}
return null;
}
IReturnType GetVariableType(LocalLookupVariable v)
{
if (v == null) {
return null;
}
IClass c = SearchType(v.TypeRef.SystemType, callingClass, cu);
if (c != null) {
return new ReturnType(c.FullyQualifiedName, v.TypeRef.RankSpecifier, v.TypeRef.PointerNestingLevel);
} else {
return new ReturnType(v.TypeRef);
}
}
#endregion
#region DynamicLookup
/// <remarks>
/// does the dynamic lookup for the typeName
/// does the dynamic lookup for the identifier
/// </remarks>
public IReturnType DynamicLookup(string typeName)
{
// try if it exists a variable named typeName
IReturnType variable = GetVariableType(SearchVariable(typeName));
if (variable != null) {
showStatic = false;
return variable;
}
@ -524,85 +555,29 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -524,85 +555,29 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
// try if typeName is a method parameter
IParameter parameter = SearchMethodParameter(typeName);
if (parameter != null) {
showStatic = false;
return parameter.ReturnType;
}
// check if typeName == value in set method of a property
if (typeName == "value") {
IProperty property = GetProperty();
IProperty property = callingMember as IProperty;
if (property != null && property.SetterRegion != null && property.SetterRegion.IsInside(caretLine, caretColumn)) {
showStatic = false;
return property.ReturnType;
}
}
// try if there exists a nonstatic member named typeName
showStatic = false;
IReturnType t = SearchMember(callingClass == null ? null : new ReturnType(callingClass.FullyQualifiedName), typeName);
IReturnType t = SearchMember(callingClass, typeName);
if (t != null) {
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
List<IClass> classes = cu.GetOuterClasses(caretLine, caretColumn);
foreach (IClass c in classes) {
t = SearchMember(callingClass == null ? null : new ReturnType(c.FullyQualifiedName), typeName);
if (t != null) {
showStatic = false;
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;
IMember member = GetMember(c, typeName);
if (member != null && member.IsStatic) {
return member.ReturnType;
}
}
return null;
@ -610,7 +585,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -610,7 +585,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
IParameter SearchMethodParameter(string parameter)
{
IMethod method = GetMethod(caretLine, caretColumn);
IMethod method = callingMember as IMethod;
if (method == null) {
return null;
}
@ -622,116 +597,37 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -622,116 +597,37 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return null;
}
/// <remarks>
/// 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)
IReturnType GetVariableType(LocalLookupVariable v)
{
this.caretLine = caretLineNumber;
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) {
if (v == null) {
return null;
}
NRefactoryASTConvertVisitor cSharpVisitor = new NRefactoryASTConvertVisitor(parseInfo.MostRecentCompilationUnit != null ? parseInfo.MostRecentCompilationUnit.ProjectContent : null);
ICSharpCode.NRefactory.Parser.AST.CompilationUnit fileCompilationUnit = parseInfo.MostRecentCompilationUnit.Tag as ICSharpCode.NRefactory.Parser.AST.CompilationUnit;
cu = (ICompilationUnit)cSharpVisitor.Visit(fileCompilationUnit, null);
if (cu != null) {
callingClass = cu.GetInnermostClass(caretLine, caretColumn);
}
if (callingClass == null) {
return null;
IClass c = SearchType(v.TypeRef.SystemType, callingClass, cu);
if (c != null) {
return new ReturnType(c.FullyQualifiedName, v.TypeRef.RankSpecifier, v.TypeRef.PointerNestingLevel);
} else {
return new ReturnType(v.TypeRef);
}
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
IParameter parameter = SearchMethodParameter(expression);
if (parameter != null) {
return new FilePosition(fileName, new Point(parameter.Region.BeginColumn, parameter.Region.BeginLine));
}
LocalLookupVariable SearchVariable(string name)
{
ArrayList variables = (ArrayList)lookupTableVisitor.variables[IsCaseSensitive(language) ? name : name.ToLower()];
if (variables == null || variables.Count <= 0) {
return null;
}
string target = expression.Substring(0, expression.LastIndexOf('.'));
string member = expression.Substring(expression.LastIndexOf('.') + 1);
p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(language, new System.IO.StringReader(target));
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));
foreach (LocalLookupVariable v in variables) {
if (IsInside(new Point(caretColumn, caretLine), v.StartPos, v.EndPos)) {
return v;
}
return null;
}
return null;
}
#endregion
#endregion
/*
public ArrayList NewCompletion(int caretLine, int caretColumn, string fileName)
{
if (!IsCaseSensitive(language)) {
@ -764,7 +660,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -764,7 +660,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
}
return result;
}
}*/
public ArrayList CtrlSpace(int caretLine, int caretColumn, string fileName)
{
@ -785,14 +681,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -785,14 +681,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (cu != null) {
callingClass = cu.GetInnermostClass(caretLine, caretColumn);
if (callingClass != null) {
IMethod method = GetMethod(caretLine, caretColumn);
IMethod method = callingMember as IMethod;
if (method != null) {
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.AddRange(projectContent.GetNamespaceContents(callingClass.Namespace));
bool inStatic = InStatic();
bool inStatic = true;
if (callingMember != null)
inStatic = callingMember.IsStatic;
result.AddRange(callingClass.GetAccessibleMembers(callingClass, inStatic).ToArray());
if (inStatic == false) {
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 @@ -43,36 +43,37 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
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) {
FieldReferenceExpression field = (FieldReferenceExpression)invocationExpression.TargetObject;
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);
resolver.ShowStatic = false;
if (methods.Count <= 0) {
return null;
}
// TODO: Find the right method
return ((IMethod)methods[0]).ReturnType;
return (IMethod)methods[0];
} else if (invocationExpression.TargetObject is IdentifierExpression) {
string id = ((IdentifierExpression)invocationExpression.TargetObject).Identifier;
if (resolver.CallingClass == null) {
return null;
}
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);
resolver.ShowStatic = false;
if (methods.Count <= 0) {
return null;
}
// TODO: Find the right method
return ((IMethod)methods[0]).ReturnType;
return (IMethod)methods[0];
}
// invocationExpression is delegate call
IReturnType t = invocationExpression.AcceptChildren(this, data) as IReturnType;
@ -85,7 +86,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -85,7 +86,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (methods.Count <= 0) {
return null;
}
return ((IMethod)methods[0]).ReturnType;
return (IMethod)methods[0];
}
return null;
}
@ -98,7 +99,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -98,7 +99,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
// int. generates a FieldreferenceExpression with TargetObject TypeReferenceExpression and no FieldName
if (fieldReferenceExpression.FieldName == null || fieldReferenceExpression.FieldName == "") {
if (fieldReferenceExpression.TargetObject is TypeReferenceExpression) {
resolver.ShowStatic = true;
return new ReturnType(((TypeReferenceExpression)fieldReferenceExpression.TargetObject).TypeReference);
}
}
@ -112,7 +112,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -112,7 +112,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
IClass c = resolver.SearchType(name + "." + fieldReferenceExpression.FieldName, resolver.CallingClass, resolver.CompilationUnit);
if (c != null) {
resolver.ShowStatic = true;
return new ReturnType(c.FullyQualifiedName);
}
return null;
@ -147,7 +146,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -147,7 +146,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
IClass c = resolver.SearchType(identifierExpression.Identifier, resolver.CallingClass, resolver.CompilationUnit);
if (c != null) {
resolver.ShowStatic = true;
return new ReturnType(c.FullyQualifiedName);
}
return resolver.DynamicLookup(identifierExpression.Identifier);

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

@ -0,0 +1,295 @@ @@ -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 @@ -150,6 +150,8 @@ namespace ICSharpCode.Core
}
}
} catch (Exception e) {
Console.Beep();
Console.WriteLine();
Console.WriteLine(e);
}
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 @@ -212,8 +212,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
insertedEventElements.Clear();
if (results != null) {
AddResolveResults(results.Namespaces);
AddResolveResults(results.Members);
AddResolveResults(results.GetCompletionData(ParserService.CurrentProjectContent));
}
}
}

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

@ -39,6 +39,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -39,6 +39,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
new string[] {"item", "A list item"},
new string[] {"term", "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[] {"paramref name=\"\"", "A reference to a parameter"},
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 @@ -55,7 +55,9 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
this.textArea = textArea;
initialOffset = textArea.Caret.Offset;
// TODO: Change this for the new resolver, or better merge IndexerInsight and MethodInsight.
/*
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName);
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 @@ -85,6 +87,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
// }
// }
}
*/
}
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 @@ -59,90 +59,48 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
this.textArea = textArea;
initialOffset = textArea.Caret.Offset;
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 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;
}
word = word.Trim();
// the parser works with 1 based coordinates
caretLineNumber = document.GetLineNumberForOffset(textArea.Caret.Offset) + 1;
caretColumn = textArea.Caret.Offset - document.GetLineSegment(caretLineNumber).Offset + 1;
string[] words = word.Split(' ');
bool contructorInsight = false;
if (words.Length > 1) {
contructorInsight = words[words.Length - 2] == "new";
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;
}
bool constructorInsight = false;
if (word.ToLower().StartsWith("new ")) {
constructorInsight = true;
word = word.Substring(4);
}
// // take out old method, when it isn't documented.
// if (method.Documentation == null || method.Documentation.Length == 0) {
// methods.Remove(method);
// return false;
// }
return true;
ResolveResult results = ParserService.Resolve(word, caretLineNumber, caretColumn, fileName, document.TextContent);
if (constructorInsight) {
TypeResolveResult result = results as TypeResolveResult;
if (result == null)
return;
IClass c = result.ResolvedClass;
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;
}
void AddConstructors(IClass c)
{
foreach (IMethod method in c.Methods) {
if (method.IsConstructor && !method.IsStatic) {
} else {
MethodResolveResult result = results as MethodResolveResult;
if (result == null)
return;
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);
}
}
}
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 @@ -305,7 +305,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
}
}
} catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e);
LogException(e);
}
goto case '.';
case '<':
@ -317,7 +317,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -317,7 +317,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
}
}
} catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e);
LogException(e);
}
return false;
case '(':
@ -335,7 +335,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -335,7 +335,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
}
}
} catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e);
LogException(e);
}
return false;
case '[':
@ -355,7 +355,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -355,7 +355,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
}
} catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e);
LogException(e);
}
return false;
case '.':
@ -369,7 +369,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -369,7 +369,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
}
// TextAreaPainter.IHaveTheFocusLock = false;
} catch (Exception e) {
Console.WriteLine("EXCEPTION: " + e);
LogException(e);
}
return false;
//// Alex: reparse file on ; - end of statement
@ -383,6 +383,12 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -383,6 +383,12 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
return false;
}
private void LogException(Exception ex)
{
Console.WriteLine();
Console.WriteLine("EXCEPTION: " + ex);
Console.Beep(); // notify user
}
public string GetWordBeforeCaret()
{

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

@ -392,8 +392,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -392,8 +392,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
parseInfo = ParserService.GetParseInformation(fileName);
}
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 @@ -401,8 +399,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{
if (textAreaControl.TextEditorProperties.EnableFolding) {
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});
}
}

Loading…
Cancel
Save