diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs index acbd76a1e2..0e30067cbc 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs @@ -24,8 +24,12 @@ using CSTokens = ICSharpCode.NRefactory.Parser.CSharp.Tokens; namespace CSharpBinding { - public class CSharpCompletionBinding : DefaultCodeCompletionBinding + public class CSharpCompletionBinding : NRefactoryCodeCompletionBinding { + public CSharpCompletionBinding() : base(SupportedLanguage.CSharp) + { + } + public override bool HandleKeyPress(SharpDevelopTextAreaControl editor, char ch) { CSharpExpressionFinder ef = new CSharpExpressionFinder(editor.FileName); @@ -70,36 +74,8 @@ namespace CSharpBinding return true; } } else if (ch == ',' && CodeCompletionOptions.InsightRefreshOnComma && CodeCompletionOptions.InsightEnabled) { - // Show MethodInsightWindow or IndexerInsightWindow - string documentText = editor.Text; - int oldCursor = cursor; - string textWithoutComments = ef.FilterComments(documentText, ref cursor); - int commentLength = oldCursor - cursor; - if (textWithoutComments != null) { - Stack parameters = new Stack(); - char c = '\0'; - while (cursor > 0) { - while (--cursor > 0 && - ((c = textWithoutComments[cursor]) == ',' || - char.IsWhiteSpace(c))); - if (c == '(') { - ShowInsight(editor, new MethodInsightDataProvider(cursor + commentLength, true), parameters, ch); - return true; - } else if (c == '[') { - ShowInsight(editor, new IndexerInsightDataProvider(cursor + commentLength, true), parameters, ch); - return true; - } - string expr = ef.FindExpressionInternal(textWithoutComments, cursor); - if (expr == null || expr.Length == 0) - break; - parameters.Push(ParserService.Resolve(new ExpressionResult(expr), - editor.ActiveTextAreaControl.Caret.Line + 1, - editor.ActiveTextAreaControl.Caret.Column + 1, - editor.FileName, - documentText)); - cursor = ef.LastExpressionStartPosition; - } - } + if (InsightRefreshOnComma(editor, ch)) + return true; } else if(ch == '=') { LineSegment curLine = editor.Document.GetLineSegmentForOffset(cursor); string documentText = editor.Text; @@ -172,100 +148,6 @@ namespace CSharpBinding return false; } - #region Re-show insight window - void ShowInsight(SharpDevelopTextAreaControl editor, MethodInsightDataProvider dp, Stack parameters, char charTyped) - { - int paramCount = parameters.Count; - dp.SetupDataProvider(editor.FileName, editor.ActiveTextAreaControl.TextArea); - List methods = dp.Methods; - if (methods.Count == 0) return; - bool overloadIsSure; - if (methods.Count == 1) { - overloadIsSure = true; - dp.DefaultIndex = 0; - } else { - IReturnType[] parameterTypes = new IReturnType[paramCount + 1]; - for (int i = 0; i < paramCount; i++) { - ResolveResult rr = parameters.Pop(); - if (rr != null) { - parameterTypes[i] = rr.ResolvedType; - } - } - IReturnType[][] tmp; - int[] ranking = MemberLookupHelper.RankOverloads(methods, parameterTypes, true, out overloadIsSure, out tmp); - bool multipleBest = false; - int bestRanking = -1; - int best = 0; - for (int i = 0; i < ranking.Length; i++) { - if (ranking[i] > bestRanking) { - bestRanking = ranking[i]; - best = i; - multipleBest = false; - } else if (ranking[i] == bestRanking) { - multipleBest = true; - } - } - if (multipleBest) overloadIsSure = false; - dp.DefaultIndex = best; - } - editor.ShowInsightWindow(dp); - if (overloadIsSure) { - IMethodOrProperty method = methods[dp.DefaultIndex]; - if (paramCount < method.Parameters.Count) { - IParameter param = method.Parameters[paramCount]; - ProvideContextCompletion(editor, param.ReturnType, charTyped); - } - } - } - - bool ProvideContextCompletion(SharpDevelopTextAreaControl editor, IReturnType expected, char charTyped) - { - IClass c = expected.GetUnderlyingClass(); - if (c == null) return false; - if (c.ClassType == ClassType.Enum) { - CtrlSpaceCompletionDataProvider cdp = new CtrlSpaceCompletionDataProvider(); - cdp.ForceNewExpression = true; - ContextCompletionDataProvider cache = new ContextCompletionDataProvider(cdp); - cache.activationKey = charTyped; - cache.GenerateCompletionData(editor.FileName, editor.ActiveTextAreaControl.TextArea, charTyped); - ICompletionData[] completionData = cache.CompletionData; - Array.Sort(completionData); - for (int i = 0; i < completionData.Length; i++) { - CodeCompletionData ccd = completionData[i] as CodeCompletionData; - if (ccd != null && ccd.Class != null) { - if (ccd.Class.FullyQualifiedName == expected.FullyQualifiedName) { - cache.DefaultIndex = i; - break; - } - } - } - if (cache.DefaultIndex >= 0) { - if (charTyped != ' ') cdp.InsertSpace = true; - editor.ShowCompletionWindow(cache, charTyped); - return true; - } - } - return false; - } - - private class ContextCompletionDataProvider : CachedCompletionDataProvider - { - internal char activationKey; - - internal ContextCompletionDataProvider(ICompletionDataProvider baseProvider) : base(baseProvider) - { - } - - public override CompletionDataProviderKeyResult ProcessKey(char key) - { - if (key == '=' && activationKey == '=') - return CompletionDataProviderKeyResult.BeforeStartKey; - activationKey = '\0'; - return base.ProcessKey(key); - } - } - #endregion - bool IsInComment(SharpDevelopTextAreaControl editor) { CSharpExpressionFinder ef = new CSharpExpressionFinder(editor.FileName); @@ -321,17 +203,6 @@ namespace CSharpBinding return false; } - IMember GetCurrentMember(SharpDevelopTextAreaControl editor) - { - ICSharpCode.TextEditor.Caret caret = editor.ActiveTextAreaControl.Caret; - NRefactoryResolver r = new NRefactoryResolver(ParserService.CurrentProjectContent, LanguageProperties.CSharp); - if (r.Initialize(editor.FileName, caret.Line + 1, caret.Column + 1)) { - return r.CallingMember; - } else { - return null; - } - } - #region "case"-keyword completion bool DoCaseCompletion(SharpDevelopTextAreaControl editor) { diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs index 69626deea7..a002192988 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; +using System.IO; using ICSharpCode.Core; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Parser; @@ -22,9 +23,10 @@ using VBTokens = ICSharpCode.NRefactory.Parser.VB.Tokens; namespace VBNetBinding { - public class VBNetCompletionBinding : DefaultCodeCompletionBinding + public class VBNetCompletionBinding : NRefactoryCodeCompletionBinding { public VBNetCompletionBinding() + : base(SupportedLanguage.VBNet) { // Don't use indexer insight for '[', VB uses '(' for indexer access this.EnableIndexerInsight = false; @@ -32,139 +34,18 @@ namespace VBNetBinding public override bool HandleKeyPress(SharpDevelopTextAreaControl editor, char ch) { - VBNetBinding.Parser.ExpressionFinder ef = new VBNetBinding.Parser.ExpressionFinder(); - int cursor = editor.ActiveTextAreaControl.Caret.Offset; - - if(ch == '(' && EnableMethodInsight && CodeCompletionOptions.InsightEnabled) - { + if(ch == '(' && EnableMethodInsight && CodeCompletionOptions.InsightEnabled) { editor.ShowInsightWindow(new MethodInsightDataProvider()); return true; - } - else if(ch == ',' && CodeCompletionOptions.InsightRefreshOnComma && CodeCompletionOptions.InsightEnabled) - { - // Show MethodInsightWindow or IndexerInsightWindow - string documentText = editor.Text; - int oldCursor = cursor; - string textWithoutComments = ef.FilterComments(documentText, ref cursor); - int commentLength = oldCursor - cursor; - if (textWithoutComments != null) { - Stack parameters = new Stack(); - char c = '\0'; - while (cursor > 0) { - while (--cursor > 0 && - ((c = textWithoutComments[cursor]) == ',' || - char.IsWhiteSpace(c))); - if (c == '(') - { - ShowInsight(editor, new MethodInsightDataProvider(cursor + commentLength, true), parameters, ch); - return true; - } - else if (c == '[') - { - ShowInsight(editor, new IndexerInsightDataProvider(cursor + commentLength, true), parameters, ch); - return true; - } - string expr = ef.FindExpressionInternal(textWithoutComments, cursor); - if (expr == null || expr.Length == 0) - { - break; - } - parameters.Push(ParserService.Resolve(new ExpressionResult(expr), - editor.ActiveTextAreaControl.Caret.Line + 1, - editor.ActiveTextAreaControl.Caret.Column + 1, - editor.FileName, - documentText)); - cursor = ef.LastExpressionStartPosition; - } - } + } else if(ch == ',' && CodeCompletionOptions.InsightRefreshOnComma && CodeCompletionOptions.InsightEnabled) { + if (InsightRefreshOnComma(editor, ch)) + return true; } else if (ch == '\n') { - TryDeclarationTypeInference(editor, editor.Document.GetLineSegmentForOffset(cursor)); + TryDeclarationTypeInference(editor, editor.Document.GetLineSegmentForOffset(editor.ActiveTextAreaControl.Caret.Offset)); } return base.HandleKeyPress(editor, ch); } - void ProvideContextCompletion(SharpDevelopTextAreaControl editor, IReturnType expected, char charTyped) - { - IClass c = expected.GetUnderlyingClass(); - if (c == null) return; - if (c.ClassType == ClassType.Enum) { - CtrlSpaceCompletionDataProvider cdp = new CtrlSpaceCompletionDataProvider(); - cdp.ForceNewExpression = true; - CachedCompletionDataProvider cache = new CachedCompletionDataProvider(cdp); - cache.GenerateCompletionData(editor.FileName, editor.ActiveTextAreaControl.TextArea, charTyped); - ICompletionData[] completionData = cache.CompletionData; - Array.Sort(completionData); - for (int i = 0; i < completionData.Length; i++) { - CodeCompletionData ccd = completionData[i] as CodeCompletionData; - if (ccd != null && ccd.Class != null) { - if (ccd.Class.FullyQualifiedName == expected.FullyQualifiedName) { - cache.DefaultIndex = i; - break; - } - } - } - if (cache.DefaultIndex >= 0) { - editor.ShowCompletionWindow(cache, charTyped); - } - } - } - - void ShowInsight(SharpDevelopTextAreaControl editor, MethodInsightDataProvider dp, Stack parameters, char charTyped) - { - int paramCount = parameters.Count; - dp.SetupDataProvider(editor.FileName, editor.ActiveTextAreaControl.TextArea); - List methods = dp.Methods; - if (methods.Count == 0) return; - bool overloadIsSure; - if (methods.Count == 1) { - overloadIsSure = true; - dp.DefaultIndex = 0; - } else { - IReturnType[] parameterTypes = new IReturnType[paramCount + 1]; - for (int i = 0; i < paramCount; i++) { - ResolveResult rr = parameters.Pop(); - if (rr != null) { - parameterTypes[i] = rr.ResolvedType; - } - } - IReturnType[][] tmp; - int[] ranking = MemberLookupHelper.RankOverloads(methods, parameterTypes, true, out overloadIsSure, out tmp); - bool multipleBest = false; - int bestRanking = -1; - int best = 0; - for (int i = 0; i < ranking.Length; i++) { - if (ranking[i] > bestRanking) { - bestRanking = ranking[i]; - best = i; - multipleBest = false; - } else if (ranking[i] == bestRanking) { - multipleBest = true; - } - } - if (multipleBest) overloadIsSure = false; - dp.DefaultIndex = best; - } - editor.ShowInsightWindow(dp); - if (overloadIsSure) { - IMethodOrProperty method = methods[dp.DefaultIndex]; - if (paramCount < method.Parameters.Count) { - IParameter param = method.Parameters[paramCount]; - ProvideContextCompletion(editor, param.ReturnType, charTyped); - } - } - } - - IMember GetCurrentMember(SharpDevelopTextAreaControl editor) - { - ICSharpCode.TextEditor.Caret caret = editor.ActiveTextAreaControl.Caret; - NRefactoryResolver r = new NRefactoryResolver(ParserService.CurrentProjectContent, LanguageProperties.VBNet); - if (r.Initialize(editor.FileName, caret.Line + 1, caret.Column + 1)) { - return r.CallingMember; - } else { - return null; - } - } - public override bool HandleKeyword(SharpDevelopTextAreaControl editor, string word) { // TODO: Assistance writing Methods/Fields/Properties/Events: diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Resources/Mode.xsd b/src/Libraries/ICSharpCode.TextEditor/Project/Resources/Mode.xsd index 5a01d8afdc..164f333de1 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Resources/Mode.xsd +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Resources/Mode.xsd @@ -95,6 +95,7 @@ + diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd b/src/Libraries/ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd index 74f4065591..3bed6be872 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd @@ -1,7 +1,6 @@ - - + @@ -31,7 +30,12 @@ --> - # + # + + + + # + # diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/DefaultHighlightingStrategy.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/DefaultHighlightingStrategy.cs index fea2ccf3ba..e75454dd8d 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/DefaultHighlightingStrategy.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/DefaultHighlightingStrategy.cs @@ -512,144 +512,147 @@ namespace ICSharpCode.TextEditor.Document PushCurWord(document, ref markNext, words); ++i; continue; - default: { - // highlight digits - if (!inSpan && (Char.IsDigit(ch) || (ch == '.' && i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLine.Offset + i + 1)))) && currentLength == 0) { - bool ishex = false; - bool isfloatingpoint = false; - - if (ch == '0' && i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'X') { // hex digits - const string hex = "0123456789ABCDEF"; - ++currentLength; - ++i; // skip 'x' - ++currentLength; - ishex = true; - while (i + 1 < currentLine.Length && hex.IndexOf(Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1))) != -1) { - ++i; + default: + { + // highlight digits + if (!inSpan && (Char.IsDigit(ch) || (ch == '.' && i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLine.Offset + i + 1)))) && currentLength == 0) { + bool ishex = false; + bool isfloatingpoint = false; + + if (ch == '0' && i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'X') { // hex digits + const string hex = "0123456789ABCDEF"; ++currentLength; - } - } else { - ++currentLength; - while (i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLine.Offset + i + 1))) { - ++i; - ++currentLength; - } - } - if (!ishex && i + 1 < currentLine.Length && document.GetCharAt(currentLine.Offset + i + 1) == '.') { - isfloatingpoint = true; - ++i; - ++currentLength; - while (i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLine.Offset + i + 1))) { - ++i; + ++i; // skip 'x' ++currentLength; - } - } - - if (i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'E') { - isfloatingpoint = true; - ++i; - ++currentLength; - if (i + 1 < currentLine.Length && (document.GetCharAt(currentLine.Offset + i + 1) == '+' || document.GetCharAt(currentLine.Offset + i + 1) == '-')) { - ++i; + ishex = true; + while (i + 1 < currentLine.Length && hex.IndexOf(Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1))) != -1) { + ++i; + ++currentLength; + } + } else { ++currentLength; + while (i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLine.Offset + i + 1))) { + ++i; + ++currentLength; + } } - while (i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLine.Offset + i + 1))) { + if (!ishex && i + 1 < currentLine.Length && document.GetCharAt(currentLine.Offset + i + 1) == '.') { + isfloatingpoint = true; ++i; ++currentLength; + while (i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLine.Offset + i + 1))) { + ++i; + ++currentLength; + } } - } - - if (i + 1 < currentLine.Length) { - char nextch = Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)); - if (nextch == 'F' || nextch == 'M' || nextch == 'D') { + + if (i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'E') { isfloatingpoint = true; ++i; ++currentLength; + if (i + 1 < currentLine.Length && (document.GetCharAt(currentLine.Offset + i + 1) == '+' || document.GetCharAt(currentLine.Offset + i + 1) == '-')) { + ++i; + ++currentLength; + } + while (i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLine.Offset + i + 1))) { + ++i; + ++currentLength; + } } - } - - if (!isfloatingpoint) { - bool isunsigned = false; - if (i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'U') { - ++i; - ++currentLength; - isunsigned = true; + + if (i + 1 < currentLine.Length) { + char nextch = Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)); + if (nextch == 'F' || nextch == 'M' || nextch == 'D') { + isfloatingpoint = true; + ++i; + ++currentLength; + } } - if (i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'L') { - ++i; - ++currentLength; - if (!isunsigned && i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'U') { + + if (!isfloatingpoint) { + bool isunsigned = false; + if (i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'U') { ++i; ++currentLength; + isunsigned = true; + } + if (i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'L') { + ++i; + ++currentLength; + if (!isunsigned && i + 1 < currentLine.Length && Char.ToUpper(document.GetCharAt(currentLine.Offset + i + 1)) == 'U') { + ++i; + ++currentLength; + } } } + + words.Add(new TextWord(document, currentLine, currentOffset, currentLength, DigitColor, false)); + currentOffset += currentLength; + currentLength = 0; + continue; } - - words.Add(new TextWord(document, currentLine, currentOffset, currentLength, DigitColor, false)); - currentOffset += currentLength; - currentLength = 0; - continue; - } - // Check for SPAN ENDs - if (inSpan) { - if (activeSpan.End != null && !activeSpan.End.Equals("")) { - if (currentLine.MatchExpr(activeSpan.End, i, document, activeSpan.IgnoreCase)) { - PushCurWord(document, ref markNext, words); - string regex = currentLine.GetRegString(activeSpan.End, i, document); - currentLength += regex.Length; - words.Add(new TextWord(document, currentLine, currentOffset, currentLength, activeSpan.EndColor, false)); - currentOffset += currentLength; - currentLength = 0; - i += regex.Length - 1; - currentSpanStack.Pop(); - UpdateSpanStateVariables(); - continue; - } - } - } - - // check for SPAN BEGIN - if (activeRuleSet != null) { - foreach (Span span in activeRuleSet.Spans) { - if ((!span.IsBeginSingleWord || currentLength == 0) && currentLine.MatchExpr(span.Begin, i, document, activeRuleSet.IgnoreCase)) { - PushCurWord(document, ref markNext, words); - string regex = currentLine.GetRegString(span.Begin, i, document); - - if (!OverrideSpan(regex, document, words, span, ref i)) { + // Check for SPAN ENDs + if (inSpan) { + if (activeSpan.End != null && !activeSpan.End.Equals("")) { + if (currentLine.MatchExpr(activeSpan.End, i, document, activeSpan.IgnoreCase)) { + PushCurWord(document, ref markNext, words); + string regex = currentLine.GetRegString(activeSpan.End, i, document); currentLength += regex.Length; - words.Add(new TextWord(document, currentLine, currentOffset, currentLength, span.BeginColor, false)); + words.Add(new TextWord(document, currentLine, currentOffset, currentLength, activeSpan.EndColor, false)); currentOffset += currentLength; currentLength = 0; - i += regex.Length - 1; - if (currentSpanStack == null) { - currentSpanStack = new SpanStack(); + currentSpanStack.Pop(); + UpdateSpanStateVariables(); + continue; + } + } + } + + // check for SPAN BEGIN + if (activeRuleSet != null) { + foreach (Span span in activeRuleSet.Spans) { + if ((!span.IsBeginSingleWord || currentLength == 0) + && (!span.IsBeginStartOfLine.HasValue || span.IsBeginStartOfLine.Value == (currentLength == 0 && words.TrueForAll(delegate(TextWord textWord) { return textWord.Type != TextWordType.Word; }))) + && currentLine.MatchExpr(span.Begin, i, document, activeRuleSet.IgnoreCase)) { + PushCurWord(document, ref markNext, words); + string regex = currentLine.GetRegString(span.Begin, i, document); + + if (!OverrideSpan(regex, document, words, span, ref i)) { + currentLength += regex.Length; + words.Add(new TextWord(document, currentLine, currentOffset, currentLength, span.BeginColor, false)); + currentOffset += currentLength; + currentLength = 0; + + i += regex.Length - 1; + if (currentSpanStack == null) { + currentSpanStack = new SpanStack(); + } + currentSpanStack.Push(span); + span.IgnoreCase = activeRuleSet.IgnoreCase; + + UpdateSpanStateVariables(); } - currentSpanStack.Push(span); - span.IgnoreCase = activeRuleSet.IgnoreCase; - UpdateSpanStateVariables(); + goto skip; } - - goto skip; } } - } - - // check if the char is a delimiter - if (activeRuleSet != null && (int)ch < 256 && activeRuleSet.Delimiters[(int)ch]) { - PushCurWord(document, ref markNext, words); - if (currentOffset + currentLength +1 < currentLine.Length) { - ++currentLength; + + // check if the char is a delimiter + if (activeRuleSet != null && (int)ch < 256 && activeRuleSet.Delimiters[(int)ch]) { PushCurWord(document, ref markNext, words); - goto skip; + if (currentOffset + currentLength +1 < currentLine.Length) { + ++currentLength; + PushCurWord(document, ref markNext, words); + goto skip; + } } + + ++currentLength; + skip: continue; } - - ++currentLength; - skip: continue; - } } } diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs index bb81afc0ac..a70e7a00d7 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs @@ -10,21 +10,22 @@ using System.Xml; namespace ICSharpCode.TextEditor.Document { - public class Span + public sealed class Span { bool stopEOL; HighlightColor color; - HighlightColor beginColor = null; - HighlightColor endColor = null; - char[] begin = null; - char[] end = null; - string name = null; - string rule = null; - HighlightRuleSet ruleSet = null; - bool noEscapeSequences = false; - bool ignoreCase = false; - bool isBeginSingleWord = false; - bool isEndSingleWord = false; + HighlightColor beginColor; + HighlightColor endColor; + char[] begin; + char[] end; + string name; + string rule; + HighlightRuleSet ruleSet; + bool noEscapeSequences; + bool ignoreCase; + bool isBeginSingleWord; + bool? isBeginStartOfLine; + bool isEndSingleWord; internal HighlightRuleSet RuleSet { get { @@ -50,6 +51,12 @@ namespace ICSharpCode.TextEditor.Document } } + public bool? IsBeginStartOfLine { + get { + return isBeginStartOfLine; + } + } + public bool IsBeginSingleWord { get { return isBeginSingleWord; @@ -137,7 +144,9 @@ namespace ICSharpCode.TextEditor.Document if (span["Begin"].HasAttribute("singleword")) { this.isBeginSingleWord = Boolean.Parse(span["Begin"].GetAttribute("singleword")); } - + if (span["Begin"].HasAttribute("startofline")) { + this.isBeginStartOfLine = Boolean.Parse(span["Begin"].GetAttribute("startofline")); + } if (span["End"] != null) { end = span["End"].InnerText.ToCharArray(); diff --git a/src/Libraries/NRefactory/Project/Src/Location.cs b/src/Libraries/NRefactory/Project/Src/Location.cs index 6d0ae993ce..2c23a51b21 100644 --- a/src/Libraries/NRefactory/Project/Src/Location.cs +++ b/src/Libraries/NRefactory/Project/Src/Location.cs @@ -25,21 +25,23 @@ namespace ICSharpCode.NRefactory int x, y; public int X { - get { - return x; - } - set { - x = value; - } + get { return x; } + set { x = value; } } public int Y { - get { - return y; - } - set { - y = value; - } + get { return y; } + set { y = value; } + } + + public int Line { + get { return y; } + set { y = value; } + } + + public int Column { + get { return x; } + set { x = value; } } public bool IsEmpty { diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index e6622acf9e..7a0292ef16 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -466,6 +466,7 @@ + UserControl diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/NRefactoryCodeCompletionBinding.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/NRefactoryCodeCompletionBinding.cs new file mode 100644 index 0000000000..0ac09563db --- /dev/null +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/NRefactoryCodeCompletionBinding.cs @@ -0,0 +1,263 @@ +// +// +// +// +// $Revision: 1965 $ +// + +using System; +using System.Collections.Generic; +using System.IO; +using ICSharpCode.Core; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.Parser; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.Refactoring; +using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver; +using ICSharpCode.SharpDevelop.Dom.VBNet; +using ICSharpCode.TextEditor.Document; +using ICSharpCode.TextEditor.Gui.CompletionWindow; +using VBTokens = ICSharpCode.NRefactory.Parser.VB.Tokens; +using CSTokens = ICSharpCode.NRefactory.Parser.CSharp.Tokens; + +namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor +{ + /// + /// Base class for C# and VB Code Completion Binding. + /// + public abstract class NRefactoryCodeCompletionBinding : DefaultCodeCompletionBinding + { + readonly SupportedLanguage language; + readonly int eofToken, commaToken, openParensToken, closeParensToken, openBracketToken, closeBracketToken, openBracesToken, closeBracesToken; + readonly LanguageProperties languageProperties; + + protected NRefactoryCodeCompletionBinding(SupportedLanguage language) + { + this.language = language; + if (language == SupportedLanguage.CSharp) { + eofToken = CSTokens.EOF; + commaToken = CSTokens.Comma; + openParensToken = CSTokens.OpenParenthesis; + closeParensToken = CSTokens.CloseParenthesis; + openBracketToken = CSTokens.OpenSquareBracket; + closeBracketToken = CSTokens.CloseSquareBracket; + openBracesToken = CSTokens.OpenCurlyBrace; + closeBracesToken = CSTokens.CloseCurlyBrace; + + languageProperties = LanguageProperties.CSharp; + } else { + eofToken = VBTokens.EOF; + commaToken = VBTokens.Comma; + openParensToken = VBTokens.OpenParenthesis; + closeParensToken = VBTokens.CloseParenthesis; + openBracketToken = -1; + closeBracketToken = -1; + openBracesToken = VBTokens.OpenCurlyBrace; + closeBracesToken = VBTokens.CloseCurlyBrace; + + languageProperties = LanguageProperties.VBNet; + } + } + + #region Comma Insight refresh + protected class InspectedCall + { + /// + /// position of the '(' + /// + internal Location start; + /// + /// list of location of the comma tokens. + /// + internal List commas = new List(); + /// + /// reference back to parent call - used to create a stack of inspected calls + /// + internal InspectedCall parent; + + public InspectedCall(Location start, InspectedCall parent) + { + this.start = start; + this.parent = parent; + } + } + + protected IList ResolveCallParameters(SharpDevelopTextAreaControl editor, InspectedCall call) + { + List rr = new List(); + int offset = LocationToOffset(editor, call.start); + string documentText = editor.Text; + foreach (Location loc in call.commas) { + int newOffset = LocationToOffset(editor, loc); + if (newOffset < 0) break; + string text = editor.Document.GetText(offset+1,newOffset-(offset+1)); + rr.Add(ParserService.Resolve(new ExpressionResult(text), loc.Line, loc.Column, editor.FileName, documentText)); + } + return rr; + } + + protected bool InsightRefreshOnComma(SharpDevelopTextAreaControl editor, char ch) + { + // Show MethodInsightWindow or IndexerInsightWindow + NRefactoryResolver r = new NRefactoryResolver(ParserService.CurrentProjectContent, languageProperties); + Location cursorLocation = new Location(editor.ActiveTextAreaControl.Caret.Column + 1, editor.ActiveTextAreaControl.Caret.Line + 1); + if (r.Initialize(editor.FileName, cursorLocation.Y, cursorLocation.X)) { + TextReader currentMethod = r.ExtractCurrentMethod(editor.Text); + if (currentMethod != null) { + ILexer lexer = ParserFactory.CreateLexer(language, currentMethod); + Token token; + InspectedCall call = new InspectedCall(Location.Empty, null); + call.parent = call; + while ((token = lexer.NextToken()) != null + && token.kind != eofToken + && token.Location < cursorLocation) + { + if (token.kind == commaToken) { + call.commas.Add(token.Location); + } else if (token.kind == openParensToken || token.kind == openBracketToken || token.kind == openBracesToken) { + call = new InspectedCall(token.Location, call); + } else if (token.kind == closeParensToken || token.kind == closeBracketToken || token.kind == closeBracesToken) { + call = call.parent; + } + } + int offset = LocationToOffset(editor, call.start); + if (offset >= 0 && offset < editor.Document.TextLength) { + char c = editor.Document.GetCharAt(offset); + if (c == '(') { + ShowInsight(editor, + new MethodInsightDataProvider(offset, true), + ResolveCallParameters(editor, call), + ch); + return true; + } else if (c == '[') { + ShowInsight(editor, + new IndexerInsightDataProvider(offset, true), + ResolveCallParameters(editor, call), + ch); + return true; + } else { + LoggingService.Warn("Expected '(' or '[' at start position"); + } + } + } + } + return false; + } + #endregion + + protected bool ProvideContextCompletion(SharpDevelopTextAreaControl editor, IReturnType expected, char charTyped) + { + if (expected == null) return false; + IClass c = expected.GetUnderlyingClass(); + if (c == null) return false; + if (c.ClassType == ClassType.Enum) { + CtrlSpaceCompletionDataProvider cdp = new CtrlSpaceCompletionDataProvider(); + cdp.ForceNewExpression = true; + ContextCompletionDataProvider cache = new ContextCompletionDataProvider(cdp); + cache.activationKey = charTyped; + cache.GenerateCompletionData(editor.FileName, editor.ActiveTextAreaControl.TextArea, charTyped); + ICompletionData[] completionData = cache.CompletionData; + Array.Sort(completionData); + for (int i = 0; i < completionData.Length; i++) { + CodeCompletionData ccd = completionData[i] as CodeCompletionData; + if (ccd != null && ccd.Class != null) { + if (ccd.Class.FullyQualifiedName == expected.FullyQualifiedName) { + cache.DefaultIndex = i; + break; + } + } + } + if (cache.DefaultIndex >= 0) { + if (charTyped != ' ') cdp.InsertSpace = true; + editor.ShowCompletionWindow(cache, charTyped); + return true; + } + } + return false; + } + + private class ContextCompletionDataProvider : CachedCompletionDataProvider + { + internal char activationKey; + + internal ContextCompletionDataProvider(ICompletionDataProvider baseProvider) : base(baseProvider) + { + } + + public override CompletionDataProviderKeyResult ProcessKey(char key) + { + if (key == '=' && activationKey == '=') + return CompletionDataProviderKeyResult.BeforeStartKey; + activationKey = '\0'; + return base.ProcessKey(key); + } + } + + protected void ShowInsight(SharpDevelopTextAreaControl editor, MethodInsightDataProvider dp, ICollection parameters, char charTyped) + { + int paramCount = parameters.Count; + dp.SetupDataProvider(editor.FileName, editor.ActiveTextAreaControl.TextArea); + List methods = dp.Methods; + if (methods.Count == 0) return; + bool overloadIsSure; + if (methods.Count == 1) { + overloadIsSure = true; + dp.DefaultIndex = 0; + } else { + IReturnType[] parameterTypes = new IReturnType[paramCount + 1]; + int i = 0; + foreach (ResolveResult rr in parameters) { + if (rr != null) { + parameterTypes[i] = rr.ResolvedType; + } + i++; + } + IReturnType[][] tmp; + int[] ranking = MemberLookupHelper.RankOverloads(methods, parameterTypes, true, out overloadIsSure, out tmp); + bool multipleBest = false; + int bestRanking = -1; + int best = 0; + for (i = 0; i < ranking.Length; i++) { + if (ranking[i] > bestRanking) { + bestRanking = ranking[i]; + best = i; + multipleBest = false; + } else if (ranking[i] == bestRanking) { + multipleBest = true; + } + } + if (multipleBest) overloadIsSure = false; + dp.DefaultIndex = best; + } + editor.ShowInsightWindow(dp); + if (overloadIsSure) { + IMethodOrProperty method = methods[dp.DefaultIndex]; + if (paramCount < method.Parameters.Count) { + IParameter param = method.Parameters[paramCount]; + ProvideContextCompletion(editor, param.ReturnType, charTyped); + } + } + } + + protected int LocationToOffset(SharpDevelopTextAreaControl editor, Location loc) + { + if (loc.IsEmpty || loc.Line - 1 >= editor.Document.TotalNumberOfLines) + return -1; + LineSegment seg = editor.Document.GetLineSegment(loc.Line - 1); + return seg.Offset + Math.Min(loc.Column, seg.Length) - 1; + } + + protected IMember GetCurrentMember(SharpDevelopTextAreaControl editor) + { + ICSharpCode.TextEditor.Caret caret = editor.ActiveTextAreaControl.Caret; + NRefactoryResolver r = new NRefactoryResolver(ParserService.CurrentProjectContent, languageProperties); + if (r.Initialize(editor.FileName, caret.Line + 1, caret.Column + 1)) { + return r.CallingMember; + } else { + return null; + } + } + } +} diff --git a/src/SharpDevelop.sln b/src/SharpDevelop.sln index d601f062f3..5f16b3c5f5 100644 --- a/src/SharpDevelop.sln +++ b/src/SharpDevelop.sln @@ -1,6 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 9.00 -# SharpDevelop 2.1.0.2049 +# Visual Studio 2005 +# SharpDevelop 2.1.0.2080 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}" ProjectSection(SolutionItems) = postProject EndProjectSection