diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/CompletionBinding.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/CompletionBinding.cs index 29cbc5b8b5..cce345fdfa 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/CompletionBinding.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/CompletionBinding.cs @@ -54,7 +54,7 @@ namespace Grunwald.BooBinding.CodeCompletion { switch (word.ToLower(CultureInfo.InvariantCulture)) { case "import": - editor.ShowCompletionWindow(new CodeCompletionDataProvider(new ExpressionResult("__GlobalNamespace", ExpressionContext.Type)), ' '); + editor.ShowCompletionWindow(new CodeCompletionDataProvider(new ExpressionResult("__GlobalNamespace", ExpressionContext.Importable)), ' '); return true; case "as": case "isa": diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs index 083f1a6cc4..cf53bf247c 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs @@ -171,8 +171,15 @@ namespace Grunwald.BooBinding.CodeCompletion // Now try to find the context of the expression while (--start > 0 && char.IsWhiteSpace(inText, start)); if (start > 2 && char.IsWhiteSpace(inText, start - 2) - && inText[start - 1] == 'a' && inText[start] == 's') { + && inText[start - 1] == 'a' && inText[start] == 's') + { result.Context = ExpressionContext.Type; + } else if (start > 6 && char.IsWhiteSpace(inText, start - 6) + && inText[start - 5] == 'i' && inText[start - 4] == 'm' + && inText[start - 3] == 'p' && inText[start - 2] == 'o' + && inText[start - 1] == 'r' && inText[start] == 't') + { + result.Context = ExpressionContext.Importable; } else { bool wasSquareBracket = false; int brackets = 0; diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs index e95fd411fd..7b90d4c09c 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs @@ -371,6 +371,33 @@ namespace Grunwald.BooBinding.CodeCompletion public override void OnSlicingExpression(SlicingExpression node) { ClearResult(); + Visit(node.Target); + Slice slice = node.Indices[0]; + if (slice.End != null) { + // Boo slice, returns a part of the source -> same type as source + return; + } + IReturnType rt = (resolveResult != null) ? resolveResult.ResolvedType : null; + if (rt == null) { + ClearResult(); + return; + } + List indexers = rt.GetProperties(); + // remove non-indexers: + for (int i = 0; i < indexers.Count; i++) { + if (!indexers[i].IsIndexer) + indexers.RemoveAt(i--); + } + IReturnType[] parameters = new IReturnType[node.Indices.Count]; + for (int i = 0; i < parameters.Length; i++) { + Expression expr = node.Indices[i].Begin as Expression; + if (expr != null) { + ClearResult(); + Visit(expr); + parameters[i] = (resolveResult != null) ? resolveResult.ResolvedType : null; + } + } + MakeResult(MemberLookupHelper.FindOverload(indexers.ToArray(), parameters)); } #endregion diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs index ff6c85ca9f..823a08b66c 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs @@ -176,7 +176,7 @@ namespace VBNetBinding // and possible return types. switch (word.ToLower()) { case "imports": - editor.ShowCompletionWindow(new CodeCompletionDataProvider(new ExpressionResult("Global", ExpressionContext.Type)), ' '); + editor.ShowCompletionWindow(new CodeCompletionDataProvider(new ExpressionResult("Global", ExpressionContext.Importable)), ' '); return true; case "as": editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Type), ' '); diff --git a/src/Main/Base/Project/Src/Dom/ExpressionContext.cs b/src/Main/Base/Project/Src/Dom/ExpressionContext.cs index 1e3f177cdf..7704ce2f6b 100644 --- a/src/Main/Base/Project/Src/Dom/ExpressionContext.cs +++ b/src/Main/Base/Project/Src/Dom/ExpressionContext.cs @@ -62,7 +62,11 @@ namespace ICSharpCode.SharpDevelop.Dom /// Context expects a namespace name /// using *expr*; - public static ExpressionContext Namespace = new NamespaceExpressionContext(); + public static ExpressionContext Namespace = new ImportableExpressionContext(false); + + /// Context expects an importable type (namespace or class with public static members) + /// Imports *expr*; + public static ExpressionContext Importable = new ImportableExpressionContext(true); /// Context expects a type name /// typeof(*expr*), is *expr*, using(*expr* ...) @@ -112,16 +116,32 @@ namespace ICSharpCode.SharpDevelop.Dom #endregion #region NamespaceExpressionContext - class NamespaceExpressionContext : ExpressionContext + sealed class ImportableExpressionContext : ExpressionContext { + bool allowImportClasses; + + public ImportableExpressionContext(bool allowImportClasses) + { + this.allowImportClasses = allowImportClasses; + } + public override bool ShowEntry(object o) { - return o is string; + if (o is string) + return true; + IClass c = o as IClass; + if (allowImportClasses && c != null) { + return c.HasPublicOrInternalStaticMembers; + } + return false; } public override string ToString() { - return "[" + GetType().Name + "]"; + if (allowImportClasses) + return "[ImportableExpressionContext]"; + else + return "[NamespaceExpressionContext]"; } } #endregion diff --git a/src/Main/Base/Project/Src/Dom/IClass.cs b/src/Main/Base/Project/Src/Dom/IClass.cs index f4f503bfee..d1241357dc 100644 --- a/src/Main/Base/Project/Src/Dom/IClass.cs +++ b/src/Main/Base/Project/Src/Dom/IClass.cs @@ -114,5 +114,12 @@ namespace ICSharpCode.SharpDevelop.Dom /// Return true if the specified class is a base class of this class; otherwise return false. /// Returns false when possibleBaseClass is null. bool IsTypeInInheritanceTree(IClass possibleBaseClass); + + bool HasPublicOrInternalStaticMembers { + get; + } + bool HasExtensionMethods { + get; + } } } diff --git a/src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs b/src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs index dc6cc4c4a7..1bedebc930 100644 --- a/src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs +++ b/src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs @@ -32,6 +32,56 @@ namespace ICSharpCode.SharpDevelop.Dom List events = null; IList typeParameters = null; + byte flags; + const byte hasPublicOrInternalStaticMembersFlag = 0x02; + const byte hasExtensionMethodsFlag = 0x04; + internal byte Flags { + get { + if (flags == 0) { + flags = 1; + foreach (IMember m in this.Fields) { + if (m.IsStatic && (m.IsPublic || m.IsInternal)) { + flags |= hasPublicOrInternalStaticMembersFlag; + } + } + foreach (IMember m in this.Properties) { + if (m.IsStatic && (m.IsPublic || m.IsInternal)) { + flags |= hasPublicOrInternalStaticMembersFlag; + } + } + foreach (IMember m in this.Methods) { + if (m.IsStatic && (m.IsPublic || m.IsInternal)) { + flags |= hasPublicOrInternalStaticMembersFlag; + } + } + foreach (IMember m in this.Events) { + if (m.IsStatic && (m.IsPublic || m.IsInternal)) { + flags |= hasPublicOrInternalStaticMembersFlag; + } + } + foreach (IClass c in this.InnerClasses) { + if (c.IsPublic || c.IsInternal) { + flags |= hasPublicOrInternalStaticMembersFlag; + } + } + } + return flags; + } + set { + flags = value; + } + } + public bool HasPublicOrInternalStaticMembers { + get { + return (Flags & hasPublicOrInternalStaticMembersFlag) == hasPublicOrInternalStaticMembersFlag; + } + } + public bool HasExtensionMethods { + get { + return (Flags & hasExtensionMethodsFlag) == hasExtensionMethodsFlag; + } + } + public DefaultClass(ICompilationUnit compilationUnit, string fullyQualifiedName) : base(null) { this.compilationUnit = compilationUnit; diff --git a/src/Main/Base/Project/Src/Dom/Implementations/DefaultReturnType.cs b/src/Main/Base/Project/Src/Dom/Implementations/DefaultReturnType.cs index 5a538cb036..c868762a52 100644 --- a/src/Main/Base/Project/Src/Dom/Implementations/DefaultReturnType.cs +++ b/src/Main/Base/Project/Src/Dom/Implementations/DefaultReturnType.cs @@ -77,10 +77,6 @@ namespace ICSharpCode.SharpDevelop.Dom continue; // ignore explicit interface implementations foreach (IProperty p in bc.Properties) { - if (p.IsIndexer && bc != c) { - // do not add base class indexers - continue; - } // do not add methods that were overridden bool ok = true; foreach (IProperty oldProperty in l) { diff --git a/src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs b/src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs index 564ade97bb..9700ee0b77 100644 --- a/src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs +++ b/src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs @@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Dom { public const long FileMagic = 0x11635233ED2F428C; public const long IndexFileMagic = 0x11635233ED2F427D; - public const short FileVersion = 4; + public const short FileVersion = 5; #region Cache management #if DEBUG @@ -346,6 +346,11 @@ namespace ICSharpCode.SharpDevelop.Dom WriteType(type); } writer.Write((int)c.Modifiers); + if (c is DefaultClass) { + writer.Write(((DefaultClass)c).Flags); + } else { + writer.Write((byte)0); + } writer.Write((byte)c.ClassType); WriteAttributes(c.Attributes); writer.Write(c.InnerClasses.Count); @@ -411,6 +416,7 @@ namespace ICSharpCode.SharpDevelop.Dom c.BaseTypes.Add(ReadType()); } c.Modifiers = (ModifierEnum)reader.ReadInt32(); + c.Flags = reader.ReadByte(); c.ClassType = (ClassType)reader.ReadByte(); ReadAttributes(c); count = reader.ReadInt32(); diff --git a/src/Main/Base/Project/Src/Services/File/FileService.cs b/src/Main/Base/Project/Src/Services/File/FileService.cs index 8114caf88b..e09c038c45 100644 --- a/src/Main/Base/Project/Src/Services/File/FileService.cs +++ b/src/Main/Base/Project/Src/Services/File/FileService.cs @@ -17,7 +17,6 @@ namespace ICSharpCode.Core { public class FileService { - static string currentFile; static RecentOpen recentOpen = null; public static RecentOpen RecentOpen { @@ -32,14 +31,6 @@ namespace ICSharpCode.Core { PropertyService.Set("RecentOpen", RecentOpen.ToProperties()); } - public static string CurrentFile { - get { - return currentFile; - } - set { - currentFile = value; - } - } static FileService() { @@ -86,31 +77,11 @@ namespace ICSharpCode.Core public static IWorkbenchWindow OpenFile(string fileName) { LoggingService.Info("Open file " + fileName); - // test, if file fileName exists - bool isURL = fileName.IndexOf("://") > 0; - if (!isURL) { - System.Diagnostics.Debug.Assert(FileUtility.IsValidFileName(fileName)); - - // test, if an untitled file should be opened - if (!Path.IsPathRooted(fileName)) { - foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) { - if (content.IsUntitled && content.UntitledName == fileName) { - content.WorkbenchWindow.SelectWindow(); - return content.WorkbenchWindow; - } - } - } else if (!FileUtility.TestFileExists(fileName)) { - return null; - } - } - foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) { - if (content.FileName != null) { - if (isURL ? content.FileName == fileName : FileUtility.IsEqualFileName(content.FileName, fileName)) { - content.WorkbenchWindow.SelectWindow(); - return content.WorkbenchWindow; - } - } + IWorkbenchWindow window = GetOpenFile(fileName); + if (window != null) { + window.SelectWindow(); + return window; } IDisplayBinding binding = DisplayBindingService.GetBindingPerFileName(fileName); @@ -226,8 +197,7 @@ namespace ICSharpCode.Core if (fileName == null || fileName.Length == 0) { return null; } - OpenFile(fileName); - IWorkbenchWindow window = GetOpenFile(fileName); + IWorkbenchWindow window = OpenFile(fileName); if (window == null) { return null; } diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs index 7a8f4cad02..184766394f 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs @@ -110,12 +110,17 @@ namespace ICSharpCode.SharpDevelop.Gui listView.EnsureVisible(index); } + ICompletionData[] ctrlSpaceCompletionData; + ICompletionData[] GetCompletionData() { + if (ctrlSpaceCompletionData != null) + return ctrlSpaceCompletionData; TextEditorControl editor = GetEditor(); if (editor != null) { CtrlSpaceCompletionDataProvider cdp = new CtrlSpaceCompletionDataProvider(ExpressionContext.Default); - return cdp.GenerateCompletionData(editor.FileName, editor.ActiveTextAreaControl.TextArea, '\0'); + ctrlSpaceCompletionData = cdp.GenerateCompletionData(editor.FileName, editor.ActiveTextAreaControl.TextArea, '\0'); + return ctrlSpaceCompletionData; } return new ICompletionData[0]; } @@ -146,8 +151,9 @@ namespace ICSharpCode.SharpDevelop.Gui listView.Items.Clear(); visibleEntries.Clear(); bestItem = null; - if (text.Length == 0) + if (text.Length < 2) return; + listView.BeginUpdate(); int dotPos = text.IndexOf('.'); int commaPos = text.IndexOf(','); if (commaPos < 0) { @@ -198,6 +204,7 @@ namespace ICSharpCode.SharpDevelop.Gui bestItem.Selected = true; listView.EnsureVisible(bestItem.Index); } + listView.EndUpdate(); } void AddSourceFiles(string text, int lineNumber) @@ -220,10 +227,11 @@ namespace ICSharpCode.SharpDevelop.Gui void AddSourceFile(string text, int lineNumber, ProjectItem item) { + string lowerText = text.ToLowerInvariant(); string fileName = item.FileName; string display = Path.GetFileName(fileName); if (display.Length >= text.Length) { - if (text.Equals(display.Substring(0, text.Length), StringComparison.OrdinalIgnoreCase)) { + if (display.ToLowerInvariant().IndexOf(lowerText) >= 0) { if (lineNumber > 0) { display += ", line " + lineNumber; } @@ -249,13 +257,14 @@ namespace ICSharpCode.SharpDevelop.Gui void ShowCompletionData(ICompletionData[] dataList, string text) { + string lowerText = text.ToLowerInvariant(); foreach (ICompletionData data in dataList) { CodeCompletionData ccd = data as CodeCompletionData; if (ccd == null) return; string dataText = ccd.Text; if (dataText.Length >= text.Length) { - if (text.Equals(dataText.Substring(0, text.Length), StringComparison.OrdinalIgnoreCase)) { + if (dataText.ToLowerInvariant().IndexOf(lowerText) >= 0) { if (ccd.Class != null) AddItem(ccd.Class, data.ImageIndex, data.Priority); else if (ccd.Member != null)