diff --git a/data/resources/StringResources.de.resources b/data/resources/StringResources.de.resources index 649e19a0a6..78c745cad2 100644 Binary files a/data/resources/StringResources.de.resources and b/data/resources/StringResources.de.resources differ diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/ExpressionFinder.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/ExpressionFinder.cs index 2909a86546..b22722eec3 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/ExpressionFinder.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/ExpressionFinder.cs @@ -134,6 +134,26 @@ namespace CSharpBinding.Parser } #endregion + #region RemoveLastPart + /// + /// Removed the last part of the expression. + /// + /// + /// "arr[i]" => "arr" + /// "obj.Field" => "obj" + /// "obj.Method(args,...)" => "obj.Method" + /// + public string RemoveLastPart(string expression) + { + text = expression; + offset = text.Length - 1; + ReadNextToken(); + if (curTokenType == Ident && Peek() == '.') + GetNext(); + return text.Substring(0, offset + 1); + } + #endregion + #region Find Expression public ExpressionResult FindExpression(string inText, int offset) { diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/ExpressionFinder.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/ExpressionFinder.cs index 097102e364..52f0792194 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/ExpressionFinder.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/ExpressionFinder.cs @@ -122,6 +122,23 @@ namespace VBNetBinding.Parser return -1; } + /// + /// Removed the last part of the expression. + /// + /// + /// "obj.Field" => "obj" + /// "obj.Method(args,...)" => "obj.Method" + /// + public string RemoveLastPart(string expression) + { + text = expression; + offset = text.Length - 1; + ReadNextToken(); + if (curTokenType == Ident && Peek() == '.') + GetNext(); + return text.Substring(0, offset + 1); + } + #region Comment Filter and 'inside string watcher' int initialOffset; public string FilterComments(string text, ref int offset) diff --git a/src/AddIns/Misc/HtmlHelp2/Project/Resources/HtmlHelp2Options.xfrm b/src/AddIns/Misc/HtmlHelp2/Project/Resources/HtmlHelp2Options.xfrm index 50ebbc5001..3eab8839e0 100644 --- a/src/AddIns/Misc/HtmlHelp2/Project/Resources/HtmlHelp2Options.xfrm +++ b/src/AddIns/Misc/HtmlHelp2/Project/Resources/HtmlHelp2Options.xfrm @@ -1,35 +1,43 @@ - - - - + + + + + + + + + + + - - + + + + - - - + + - \ No newline at end of file + diff --git a/src/AddIns/Misc/HtmlHelp2/Project/src/Service/HtmlHelp2Options.cs b/src/AddIns/Misc/HtmlHelp2/Project/src/Service/HtmlHelp2Options.cs index fe7c6803b2..1a9678fc2a 100644 --- a/src/AddIns/Misc/HtmlHelp2/Project/src/Service/HtmlHelp2Options.cs +++ b/src/AddIns/Misc/HtmlHelp2/Project/src/Service/HtmlHelp2Options.cs @@ -9,6 +9,7 @@ namespace HtmlHelp2Service { using System; using System.Drawing; + using System.Diagnostics; using System.Collections; using System.IO; using System.Reflection; @@ -28,6 +29,7 @@ namespace HtmlHelp2Service public override void LoadPanelContents() { SetupFromXmlStream(this.GetType().Assembly.GetManifestResourceStream("HtmlHelp2.Resources.HtmlHelp2Options.xfrm")); + ControlDictionary["reregisterButton"].Click += ReregisterButtonClick; this.InitializeComponents(); } @@ -83,5 +85,23 @@ namespace HtmlHelp2Service catch { } } + + void ReregisterButtonClick(object sender, EventArgs e) + { + new MethodInvoker(DoReregister).BeginInvoke(null, null); + } + + void DoReregister() + { + try { + ProcessStartInfo info = new ProcessStartInfo("cmd", "/c call echo Unregistering... & unregister.bat & echo. & echo Registering... & call register.bat & pause"); + info.WorkingDirectory = Path.Combine(FileUtility.SharpDevelopRootPath, "bin\\setup\\help"); + Process p = Process.Start(info); + p.WaitForExit(45000); + WorkbenchSingleton.SafeThreadAsyncCall(typeof(HtmlHelp2Environment), "ReloadNamespace"); + } catch (Exception ex) { + MessageService.ShowError(ex); + } + } } } diff --git a/src/Main/Base/Project/Src/Dom/IExpressionFinder.cs b/src/Main/Base/Project/Src/Dom/IExpressionFinder.cs index 8f496837b5..73748eb18c 100644 --- a/src/Main/Base/Project/Src/Dom/IExpressionFinder.cs +++ b/src/Main/Base/Project/Src/Dom/IExpressionFinder.cs @@ -20,6 +20,16 @@ namespace ICSharpCode.SharpDevelop.Dom /// Finds an expression around the current offset. /// ExpressionResult FindFullExpression(string text, int offset); + + /// + /// Removed the last part of the expression. + /// + /// + /// "arr[i]" => "arr" + /// "obj.Field" => "obj" + /// "obj.Method(args,...)" => "obj.Method" + /// + string RemoveLastPart(string expression); } /// diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs index 705b7712e5..d1eba94e8e 100644 --- a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs +++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs @@ -259,6 +259,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver return invocationTarget; } + } else if (expr is IndexerExpression) { + return CreateMemberResolveResult(typeVisitor.GetIndexer(expr as IndexerExpression, null)); } else if (expr is FieldReferenceExpression) { FieldReferenceExpression fieldReferenceExpression = (FieldReferenceExpression)expr; if (fieldReferenceExpression.FieldName == null || fieldReferenceExpression.FieldName.Length == 0) { diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs index 03c7acdc60..c9f5fec6b4 100644 --- a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs +++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs @@ -88,6 +88,15 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver return null; } + public override object Visit(IndexerExpression indexerExpression, object data) + { + IIndexer i = GetIndexer(indexerExpression, data); + if (i != null) + return i.ReturnType; + else + return null; + } + public IMethod FindOverload(List methods, ArrayList arguments, object data) { if (methods.Count <= 0) { @@ -201,6 +210,27 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver return null; } + public IIndexer GetIndexer(IndexerExpression indexerExpression, object data) + { + IReturnType type = (IReturnType)indexerExpression.TargetObject.AcceptVisitor(this, data); + if (type == null) { + return null; + } + List indexers = type.GetIndexers(); + IReturnType[] parameters = new IReturnType[indexerExpression.Indices.Count]; + for (int i = 0; i < parameters.Length; i++) { + Expression expr = indexerExpression.Indices[i] as Expression; + if (expr != null) + parameters[i] = (IReturnType)expr.AcceptVisitor(this, data); + } + bool tmp; + int num = FindOverload(new List(indexers.ToArray()), parameters, true, out tmp); + if (num < 0) + return null; + else + return indexers[num]; + } + void InjectMethodTypeParameters(List methods, InvocationExpression invocationExpression) { if (invocationExpression.TypeParameters == null) return; @@ -375,19 +405,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver return null; } - public override object Visit(IndexerExpression indexerExpression, object data) - { - IReturnType type = (IReturnType)indexerExpression.TargetObject.AcceptVisitor(this, data); - if (type == null) { - return null; - } - List indexers = type.GetIndexers(); - if (indexers.Count > 0) - return indexers[0].ReturnType; - else - return null; - } - public override object Visit(ClassReferenceExpression classReferenceExpression, object data) { if (resolver.CallingClass == null) { diff --git a/src/Main/Base/Project/Src/Dom/ResolveResult.cs b/src/Main/Base/Project/Src/Dom/ResolveResult.cs index 1c2cf407e0..f3493ec992 100644 --- a/src/Main/Base/Project/Src/Dom/ResolveResult.cs +++ b/src/Main/Base/Project/Src/Dom/ResolveResult.cs @@ -443,14 +443,23 @@ namespace ICSharpCode.SharpDevelop.Dom } } - public override FilePosition GetDefinitionPosition() + public IMethod GetMethodIfSingleOverload() { List methods = containingType.GetMethods(); methods = methods.FindAll(delegate(IMethod m) { return m.Name == this.Name; }); - if (methods.Count == 1) { - return MemberResolveResult.GetDefinitionPosition(methods[0]); - } - return base.GetDefinitionPosition(); + if (methods.Count == 1) + return methods[0]; + else + return null; + } + + public override FilePosition GetDefinitionPosition() + { + IMethod m = GetMethodIfSingleOverload(); + if (m != null) + return MemberResolveResult.GetDefinitionPosition(m); + else + return base.GetDefinitionPosition(); } } #endregion diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs index 06b882038e..73805e59ff 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs @@ -363,15 +363,12 @@ namespace ICSharpCode.Core else return ambience.Convert(result.ResolvedType); } else if (result is MethodResolveResult) { - IReturnType container = ((MethodResolveResult)result).ContainingType; - List methods = container.GetMethods(); - methods = methods.FindAll(delegate(IMethod m) { - return m.Name == ((MethodResolveResult)result).Name; - }); - if (methods.Count == 1) - return GetText(ambience, methods[0]); + MethodResolveResult mrr = result as MethodResolveResult; + IMethod m = mrr.GetMethodIfSingleOverload(); + if (m != null) + return GetText(ambience, m); else - return "Overload of " + ambience.Convert(container) + "." + ((MethodResolveResult)result).Name; + return "Overload of " + ambience.Convert(mrr.ContainingType) + "." + mrr.Name; } else { // if (result.ResolvedType != null) // return "expression of type " + ambience.Convert(result.ResolvedType); diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs index 31e7576133..e90f02f6df 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs @@ -96,6 +96,11 @@ namespace ICSharpCode.Core if (progressMonitor != null) { progressMonitor.BeginTask("${res:SharpDevelop.Refactoring.FindingReferences}", files.Count); } + #if DEBUG + if (System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Control) { + System.Diagnostics.Debugger.Break(); + } + #endif while (enumerator.MoveNext()) { if (progressMonitor != null) { progressMonitor.WorkDone = enumerator.Index; @@ -144,17 +149,28 @@ namespace ICSharpCode.Core if (expressionFinder == null) { expressionFinder = ParserService.GetExpressionFinder(fileName); } - ExpressionResult expr = expressionFinder.FindFullExpression(fileContent, pos + 1); + ExpressionResult expr = expressionFinder.FindFullExpression(fileContent, pos); if (expr.Expression != null) { Point position = GetPosition(fileContent, pos); + repeatResolve: // TODO: Optimize by re-using the same resolver if multiple expressions were // found in this file (the resolver should parse all methods at once) ResolveResult rr = ParserService.Resolve(expr, position.Y, position.X, fileName, fileContent); if (member != null) { + // find reference to member if (IsReferenceToMember(member, rr)) { list.Add(new Reference(fileName, pos, searchedText.Length, expr.Expression, rr)); + } else if (rr is MemberResolveResult && (rr as MemberResolveResult).ResolvedMember is IIndexer) { + // we got an indexer call as expression ("objectList[0].ToString()[2]") + // strip the index from the expression to resolve the underlying expression + string newExpr = expressionFinder.RemoveLastPart(expr.Expression); + if (newExpr.Length >= expr.Expression.Length) + throw new ApplicationException("new expression must be shorter than old expression"); + expr.Expression = newExpr; + goto repeatResolve; } } else { + // find reference to class MemberResolveResult mrr = rr as MemberResolveResult; if (mrr != null) { if (mrr.ResolvedMember is IMethod && ((IMethod)mrr.ResolvedMember).IsConstructor) { @@ -270,7 +286,7 @@ namespace ICSharpCode.Core continue; } if (!pc.HasReferenceTo(ownerProjectContent)) { - // unreferences project contents cannot reference the class + // project contents that do not reference the owner's content cannot reference the member continue; } } @@ -286,10 +302,13 @@ namespace ICSharpCode.Core public static bool IsReferenceToMember(IMember member, ResolveResult rr) { MemberResolveResult mrr = rr as MemberResolveResult; - if (mrr != null) + if (mrr != null) { return IsSimilarMember(mrr.ResolvedMember, member); - else + } else if (rr is MethodResolveResult) { + return IsSimilarMember((rr as MethodResolveResult).GetMethodIfSingleOverload(), member); + } else { return false; + } } /// @@ -363,6 +382,7 @@ namespace ICSharpCode.Core public static IMember FindBaseMember(IMember member) { + if (member == null) return null; IClass parentClass = member.DeclaringType; IClass baseClass = parentClass.BaseClass; if (baseClass == null) return null; diff --git a/src/Main/StartUp/Project/Resources/StringResources.resources b/src/Main/StartUp/Project/Resources/StringResources.resources index 0ddadd3ec9..57d6d5be86 100644 Binary files a/src/Main/StartUp/Project/Resources/StringResources.resources and b/src/Main/StartUp/Project/Resources/StringResources.resources differ diff --git a/src/Tools/Help/plugins.xml b/src/Tools/Help/plugins.xml index 6c42f0052e..1b2d24bc57 100644 --- a/src/Tools/Help/plugins.xml +++ b/src/Tools/Help/plugins.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/Tools/Help/register.xml b/src/Tools/Help/register.xml index f2e5732da0..6da79ac7bd 100644 --- a/src/Tools/Help/register.xml +++ b/src/Tools/Help/register.xml @@ -5,7 +5,7 @@ - + \ No newline at end of file