Browse Source

Fixed SD2-1189: VB: #-delimited dates not supported by syntax highlighting and expression finder

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2087 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
0e00c678ce
  1. 143
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs
  2. 135
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs
  3. 1
      src/Libraries/ICSharpCode.TextEditor/Project/Resources/Mode.xsd
  4. 10
      src/Libraries/ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd
  5. 219
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/DefaultHighlightingStrategy.cs
  6. 35
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs
  7. 26
      src/Libraries/NRefactory/Project/Src/Location.cs
  8. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  9. 263
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/NRefactoryCodeCompletionBinding.cs
  10. 3
      src/SharpDevelop.sln

143
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs

@ -24,8 +24,12 @@ using CSTokens = ICSharpCode.NRefactory.Parser.CSharp.Tokens; @@ -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 @@ -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<ResolveResult> parameters = new Stack<ResolveResult>();
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 @@ -172,100 +148,6 @@ namespace CSharpBinding
return false;
}
#region Re-show insight window
void ShowInsight(SharpDevelopTextAreaControl editor, MethodInsightDataProvider dp, Stack<ResolveResult> parameters, char charTyped)
{
int paramCount = parameters.Count;
dp.SetupDataProvider(editor.FileName, editor.ActiveTextAreaControl.TextArea);
List<IMethodOrProperty> 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 @@ -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)
{

135
src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs

@ -7,6 +7,7 @@ @@ -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; @@ -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 @@ -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<ResolveResult> parameters = new Stack<ResolveResult>();
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<ResolveResult> parameters, char charTyped)
{
int paramCount = parameters.Count;
dp.SetupDataProvider(editor.FileName, editor.ActiveTextAreaControl.TextArea);
List<IMethodOrProperty> 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:

1
src/Libraries/ICSharpCode.TextEditor/Project/Resources/Mode.xsd

@ -95,6 +95,7 @@ @@ -95,6 +95,7 @@
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="singleword" type="xsd:boolean" />
<xsd:attribute name="startofline" type="xsd:boolean" />
<!-- The default rendering style for the Begin symbol. If not specified
the defaul rendering style for the span will be used. -->
<xsd:attribute name="bold" type="xsd:boolean" />

10
src/Libraries/ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
<?xml version="1.0"?>
<!-- Syntaxdefinition for VB.NET Beta Cycle, v0.1 Rev 1 by Christian Holm -->
<!-- compliant with SharpDevelop v0.65ST2 -->
<!-- Syntaxdefinition for VB.NET, v0.1 Rev 1 by Christian Holm -->
<!-- Updated 2005 by Daniel Grunwald for VB.NET 2.0 -->
<SyntaxDefinition name = "VBNET" extensions = ".vb">
@ -31,7 +30,12 @@ @@ -31,7 +30,12 @@
</Span>
-->
<Span name = "PREPROCESSORDIRECTIVE" rule = "PreprocessorSet" bold = "false" italic = "false" color = "Maroon" stopateol = "true">
<Begin>#</Begin>
<Begin startofline="true">#</Begin>
</Span>
<Span name = "DATELITERAL" bold = "false" italic = "false" color = "Blue" stopateol = "true">
<Begin startofline="false">#</Begin>
<End>#</End>
</Span>
<Span name = "LINECOMMENT" bold = "false" italic = "false" color = "Green" stopateol = "true">

219
src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/DefaultHighlightingStrategy.cs

@ -512,144 +512,147 @@ namespace ICSharpCode.TextEditor.Document @@ -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;
}
}
}

35
src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs

@ -10,21 +10,22 @@ using System.Xml; @@ -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 @@ -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 @@ -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();

26
src/Libraries/NRefactory/Project/Src/Location.cs

@ -25,21 +25,23 @@ namespace ICSharpCode.NRefactory @@ -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 {

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

@ -466,6 +466,7 @@ @@ -466,6 +466,7 @@
<Compile Include="Src\TextEditor\Gui\Editor\InsightWindow\MethodInsightDataProvider.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\ErrorDrawer.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\ITextAreaControlProvider.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\NRefactoryCodeCompletionBinding.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\ParserFoldingStrategy.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\QuickClassBrowserPanel.cs">
<SubType>UserControl</SubType>

263
src/Main/Base/Project/Src/TextEditor/Gui/Editor/NRefactoryCodeCompletionBinding.cs

@ -0,0 +1,263 @@ @@ -0,0 +1,263 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 1965 $</version>
// </file>
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
{
/// <summary>
/// Base class for C# and VB Code Completion Binding.
/// </summary>
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
{
/// <summary>
/// position of the '('
/// </summary>
internal Location start;
/// <summary>
/// list of location of the comma tokens.
/// </summary>
internal List<Location> commas = new List<Location>();
/// <summary>
/// reference back to parent call - used to create a stack of inspected calls
/// </summary>
internal InspectedCall parent;
public InspectedCall(Location start, InspectedCall parent)
{
this.start = start;
this.parent = parent;
}
}
protected IList<ResolveResult> ResolveCallParameters(SharpDevelopTextAreaControl editor, InspectedCall call)
{
List<ResolveResult> rr = new List<ResolveResult>();
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<ResolveResult> parameters, char charTyped)
{
int paramCount = parameters.Count;
dp.SetupDataProvider(editor.FileName, editor.ActiveTextAreaControl.TextArea);
List<IMethodOrProperty> 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;
}
}
}
}

3
src/SharpDevelop.sln

@ -1,6 +1,7 @@ @@ -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

Loading…
Cancel
Save