Учет случая params в TipPainterTools при подсветке (#3318)

* Refactor LanguageInformation classes

* Improve extension check in TipPainterTools

* Refactor parsing parameters for signature help

* Fix TipPainterTools Linux version

* Add Params check in TipPainterTools
This commit is contained in:
AlexanderZemlyak 2025-07-05 11:05:34 +03:00 committed by GitHub
parent a1584f4f90
commit 6fa1caa034
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 370 additions and 346 deletions

View file

@ -2535,7 +2535,8 @@ namespace CodeCompletion
return is_constructor;
}
public override void MakeSynonimDescription()
// не используется нигде для ProcScope EVA
public override void MakeSynonimDescription()
{
//aliased = true;
si.description = CodeCompletionController.CurrentParser?.LanguageInformation.GetSynonimDescription(this);

View file

@ -21,6 +21,8 @@ namespace Languages.SPython.Frontend.Data
public override string ParameterDelimiter => ",";
public override string DelimiterInIndexer => ",";
public override string ResultVariableName => null;
public override string ProcedureName => null;
@ -43,6 +45,13 @@ namespace Languages.SPython.Frontend.Data
public override bool UsesFunctionsOverlappingSourceContext => true;
protected override string IntTypeName => "int";
public override bool IsParams(string paramDescription)
{
return paramDescription.TrimStart().StartsWith("params");
}
private readonly Dictionary<string, string> renamings = new Dictionary<string, string>
{
["biginteger"] = "bigint"

View file

@ -20,6 +20,8 @@ namespace PascalABCCompiler.Parsers
public abstract string ParameterDelimiter { get; }
public abstract string DelimiterInIndexer { get; }
public abstract string ResultVariableName { get; }
public abstract string GenericTypesStartBracket { get; }
@ -42,6 +44,10 @@ namespace PascalABCCompiler.Parsers
public virtual Dictionary<string, string> SpecialModulesAliases => null;
protected abstract string IntTypeName { get; }
public abstract bool IsParams(string paramDescription);
public virtual void RenameOrExcludeSpecialNames(SymInfo[] symInfos) { }
// перенести сюда реализацию EVA
@ -142,10 +148,143 @@ namespace PascalABCCompiler.Parsers
protected abstract string GetFullTypeName(Type ctn, bool no_alias = true);
// перенести реализацию сюда EVA
public virtual string[] GetIndexerString(IBaseScope scope)
protected string GetDescriptionForProcedure(IProcScope scope)
{
return null;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
string extensionType = null;
if (scope.IsExtension && scope.Parameters.Length > 0)
{
extensionType = GetSimpleDescription(scope.Parameters[0].Type);
}
if (scope.IsExtension)
{
if (extensionType != null && extensionType.IndexOf(' ') != -1)
{
sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + " " + extensionType + ") ");
extensionType = null;
}
else
{
sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + ") ");
}
}
if (scope.IsStatic) sb.Append("static ");
if (scope.IsConstructor())
sb.Append("constructor ");
else
if (scope.ReturnType == null && ProcedureName != null)
sb.Append(ProcedureName + " ");
else
sb.Append(FunctionName + " ");
if (!scope.IsConstructor())
{
if (extensionType != null)
{
sb.Append(extensionType + ".");
sb.Append(scope.Name);
}
else
{
sb.Append(GetTopScopeName(scope.TopScope));
sb.Append(scope.Name);
}
}
else
{
sb.Append(GetTopScopeNameWithoutDot(scope.TopScope));
}
/*string[] template_args = scope.TemplateParameters;
if (template_args != null)
{
sb.Append('<');
for (int i=0; i<template_args.Length; i++)
{
sb.Append(template_args[i]);
if (i < template_args.Length-1)
sb.Append(',');
}
sb.Append('>');
}*/
sb.Append(GetGenericString(scope.TemplateParameters));
sb.Append('(');
IElementScope[] parameters = scope.Parameters;
for (int i = 0; i < parameters.Length; i++)
{
if (scope.IsExtension && i == 0)
continue;
sb.Append(GetSimpleDescription(parameters[i]));
if (i < parameters.Length - 1)
{
sb.Append("; ");
}
}
sb.Append(')');
if (scope.ReturnType != null && !scope.IsConstructor() && !(scope.ReturnType is IProcType && (scope.ReturnType as IProcType).Target == scope))
sb.Append(ReturnTypeDelimiter + " " + GetSimpleDescription(scope.ReturnType));
//if (scope.IsStatic) sb.Append("; static");
if (scope.IsVirtual) sb.Append("; ");
else if (scope.IsAbstract) sb.Append("; abstract");
else if (scope.IsOverride) sb.Append("; override");
else if (scope.IsReintroduce) sb.Append("; reintroduce");
sb.Append(';');
return sb.ToString();
}
public string[] GetIndexerString(IBaseScope scope)
{
IBaseScope tmp_si = scope;
if (scope == null) return null;
if (scope is IElementScope)
if ((scope as IElementScope).Indexers.Length == 0)
scope = (scope as IElementScope).Type;
if (scope is IProcScope) scope = (scope as IProcScope).ReturnType;
if (!(scope is IElementScope))
{
ITypeScope ts = scope as ITypeScope;
if (ts == null) return null;
ITypeScope[] indexers = ts.Indexers;
if (tmp_si is ITypeScope)
indexers = ts.StaticIndexers;
if ((indexers == null || indexers.Length == 0) && !(ts is IArrayScope))
return null;
StringBuilder sb = new StringBuilder();
if (!(tmp_si is ITypeScope))
sb.Append("this");
else
sb.Append(GetSimpleDescriptionWithoutNamespace(tmp_si as ITypeScope));
sb.Append('[');
if (indexers != null)
for (int i = 0; i < indexers.Length; i++)
{
sb.Append(GetSimpleDescriptionWithoutNamespace(indexers[i]));
if (i < indexers.Length - 1)
sb.Append(',');
}
else
sb.Append(IntTypeName);
sb.Append("] : ");
sb.Append(GetSimpleDescriptionWithoutNamespace(ts.ElementType));
return new string[1] { sb.ToString() };
}
else
{
IElementScope es = scope as IElementScope;
ITypeScope[] indexers = es.Indexers;
if (indexers == null || indexers.Length == 0 || es.ElementType == null) return null;
StringBuilder sb = new StringBuilder();
sb.Append(es.Name);
sb.Append('[');
for (int i = 0; i < indexers.Length; i++)
{
sb.Append(GetSimpleDescriptionWithoutNamespace(indexers[i]));
if (i < indexers.Length - 1)
sb.Append(',');
}
sb.Append("] : ");
sb.Append(GetSimpleDescriptionWithoutNamespace(es.ElementType));
return new string[1] { sb.ToString() };
}
}
public abstract string GetKeyword(SymbolKind kind);
@ -202,7 +341,6 @@ namespace PascalABCCompiler.Parsers
return scope.Name + template_str;
}
// TODO: Адаптировать к многоязычности EVA
protected string GetDescriptionForCompiledMethod(ICompiledMethodScope scope)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
@ -1019,5 +1157,83 @@ namespace PascalABCCompiler.Parsers
}
return GetFullTypeName(t, no_alias);
}
public int FindClosingParenthesis(string descriptionAfterOpeningParenthesis, char parenthesis)
{
char openingParenthesis = parenthesis == ')' ? '(' : '[';
int count = 1;
int i = 0;
foreach (char c in descriptionAfterOpeningParenthesis)
{
if (c == openingParenthesis)
{
count++;
}
else if (c == parenthesis)
{
count--;
}
if (count == 0)
{
break;
}
i++;
}
return i;
}
public int FindParamDelim(string descriptionAfterOpeningParenthesis, int number) => FindParamDelim(descriptionAfterOpeningParenthesis, number, ParameterDelimiter);
public int FindParamDelimForIndexer(string descriptionAfterOpeningParenthesis, int number) => FindParamDelim(descriptionAfterOpeningParenthesis, number, DelimiterInIndexer);
public int FindParamDelim(string descriptionAfterOpeningParenthesis, int number, string paramDelim)
{
int count = 1;
int i = 0;
int delimNum = 0;
foreach (char c in descriptionAfterOpeningParenthesis)
{
if (c == '(' || c == '[' || c == '<' || c == '{')
{
count++;
}
else if (c == ')' || c == ']' || c == '>' || c == '}')
{
count--;
}
if (count == 0)
{
break;
}
// если не внутри внутренних скобок
else if (count == 1)
{
if (descriptionAfterOpeningParenthesis.Substring(i).StartsWith(paramDelim))
{
delimNum++;
if (delimNum == number)
break;
}
}
i++;
}
if (delimNum < number || i == descriptionAfterOpeningParenthesis.Length)
return -1;
return i;
}
}
}

View file

@ -132,6 +132,14 @@ namespace PascalABCCompiler.Parsers
void RenameOrExcludeSpecialNames(SymInfo[] symInfos);
bool IsParams(string paramDescription);
int FindClosingParenthesis(string descriptionAfterOpeningParenthesis, char parenthesis);
int FindParamDelim(string descriptionAfterOpeningParenthesis, int number);
int FindParamDelimForIndexer(string descriptionAfterOpeningParenthesis, int number);
Dictionary<string, string> SpecialModulesAliases { get; }
BaseKeywords KeywordsStorage
@ -156,6 +164,10 @@ namespace PascalABCCompiler.Parsers
{
get;
}
string DelimiterInIndexer
{
get;
}
string ResultVariableName
{
get;

View file

@ -122,6 +122,8 @@ namespace Languages.Pascal.Frontend.Data
}
}
public override string DelimiterInIndexer => ",";
public override string ResultVariableName => "Result";
public override string ProcedureName => "procedure";
@ -134,6 +136,8 @@ namespace Languages.Pascal.Frontend.Data
public override string ReturnTypeDelimiter => ":";
protected override string IntTypeName => "integer";
public override bool CaseSensitive
{
get
@ -156,6 +160,11 @@ namespace Languages.Pascal.Frontend.Data
public override bool UsesFunctionsOverlappingSourceContext => false;
public override bool IsParams(string paramDescription)
{
return paramDescription.Contains("...") || paramDescription.TrimStart().StartsWith("params");
}
public override string GetDescription(IBaseScope scope)
{
switch (scope.Kind)
@ -1315,89 +1324,6 @@ namespace Languages.Pascal.Frontend.Data
return "namespace " + scope.Name;
}
protected string GetDescriptionForProcedure(IProcScope scope)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
string extensionType = null;
if (scope.IsExtension && scope.Parameters.Length > 0)
{
extensionType = GetSimpleDescription(scope.Parameters[0].Type);
}
if (scope.IsExtension)
{
if (extensionType != null && extensionType.IndexOf(' ') != -1)
{
sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + " " + extensionType + ") ");
extensionType = null;
}
else
{
sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION")+ ") ");
}
}
if (scope.IsStatic) sb.Append("static ");
if (scope.IsConstructor())
sb.Append("constructor ");
else
if (scope.ReturnType == null)
sb.Append("procedure ");
else
sb.Append("function ");
if (!scope.IsConstructor())
{
if (extensionType != null)
{
sb.Append(extensionType + ".");
sb.Append(scope.Name);
}
else
{
sb.Append(GetTopScopeName(scope.TopScope));
sb.Append(scope.Name);
}
}
else
{
sb.Append(GetTopScopeNameWithoutDot(scope.TopScope));
}
/*string[] template_args = scope.TemplateParameters;
if (template_args != null)
{
sb.Append('<');
for (int i=0; i<template_args.Length; i++)
{
sb.Append(template_args[i]);
if (i < template_args.Length-1)
sb.Append(',');
}
sb.Append('>');
}*/
sb.Append(GetGenericString(scope.TemplateParameters));
sb.Append('(');
IElementScope[] parameters = scope.Parameters;
for (int i = 0; i < parameters.Length; i++)
{
if (scope.IsExtension && i == 0)
continue;
sb.Append(GetSimpleDescription(parameters[i]));
if (i < parameters.Length - 1)
{
sb.Append("; ");
}
}
sb.Append(')');
if (scope.ReturnType != null && !scope.IsConstructor() && !(scope.ReturnType is IProcType && (scope.ReturnType as IProcType).Target == scope))
sb.Append(ReturnTypeDelimiter + " " + GetSimpleDescription(scope.ReturnType));
//if (scope.IsStatic) sb.Append("; static");
if (scope.IsVirtual) sb.Append("; ");
else if (scope.IsAbstract) sb.Append("; abstract");
else if (scope.IsOverride) sb.Append("; override");
else if (scope.IsReintroduce) sb.Append("; reintroduce");
sb.Append(';');
return sb.ToString();
}
protected string GetDescriptionForCompiledEvent(EventInfo ei)
{
MethodInfo add_meth = ei.GetAddMethod(true);
@ -1499,62 +1425,6 @@ namespace Languages.Pascal.Frontend.Data
return "type " + scope.Name + " = " + scope.Description;
}
public string[] GetIndexerString(IBaseScope scope)
{
IBaseScope tmp_si = scope;
if (scope == null) return null;
if (scope is IElementScope)
if ((scope as IElementScope).Indexers.Length == 0)
scope = (scope as IElementScope).Type;
if (scope is IProcScope) scope = (scope as IProcScope).ReturnType;
if (!(scope is IElementScope))
{
ITypeScope ts = scope as ITypeScope;
if (ts == null) return null;
ITypeScope[] indexers = ts.Indexers;
if (tmp_si is ITypeScope)
indexers = ts.StaticIndexers;
if ((indexers == null || indexers.Length == 0) && !(ts is IArrayScope))
return null;
StringBuilder sb = new StringBuilder();
if (!(tmp_si is ITypeScope))
sb.Append("this");
else
sb.Append(GetSimpleDescriptionWithoutNamespace(tmp_si as ITypeScope));
sb.Append('[');
if (indexers != null)
for (int i = 0; i < indexers.Length; i++)
{
sb.Append(GetSimpleDescriptionWithoutNamespace(indexers[i]));
if (i < indexers.Length - 1)
sb.Append(',');
}
else
sb.Append("integer");
sb.Append("] : ");
sb.Append(GetSimpleDescriptionWithoutNamespace(ts.ElementType));
return new string[1] { sb.ToString() };
}
else
{
IElementScope es = scope as IElementScope;
ITypeScope[] indexers = es.Indexers;
if (indexers == null || indexers.Length == 0 || es.ElementType == null) return null;
StringBuilder sb = new StringBuilder();
sb.Append(es.Name);
sb.Append('[');
for (int i = 0; i < indexers.Length; i++)
{
sb.Append(GetSimpleDescriptionWithoutNamespace(indexers[i]));
if (i < indexers.Length - 1)
sb.Append(',');
}
sb.Append("] : ");
sb.Append(GetSimpleDescriptionWithoutNamespace(es.ElementType));
return new string[1] { sb.ToString() };
}
}
private string GetSimpleSynonimDescription(ITypeSynonimScope scope)
{
return scope.Name;

View file

@ -26,7 +26,7 @@ namespace ICSharpCode.TextEditor.Gui.CompletionWindow
//pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
if (Description != null && Description.Length > 0) {
if (!in_completion_list)
ICSharpCode.TextEditor.Util.TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, null, Description,-1,false);
ICSharpCode.TextEditor.Util.TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, null, Description,-1, -1, false);
else
{
if (has_tags())

View file

@ -167,15 +167,16 @@ namespace ICSharpCode.TextEditor.Gui.InsightWindow
}
//pe.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
int num_param = (DataProvider as VisualPascalABC.DefaultInsightDataProvider).num_param;
drawingSize = TipPainterTools.GetDrawingSizeHelpTipFromCombinedDescription(this,
int paramsCount = (DataProvider as VisualPascalABC.DefaultInsightDataProvider).param_count;
drawingSize = TipPainterTools.GetDrawingSizeHelpTipFromCombinedDescription(this,
pe.Graphics,
Font,
methodCountMessage,
description,num_param,true);
description,num_param, paramsCount, true);
if (drawingSize != Size) {
SetLocation();
} else {
TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, methodCountMessage, description, num_param,true);
TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, methodCountMessage, description, num_param, paramsCount, true);
}
lastCursorScreenPosition = control.ActiveTextAreaControl.TextArea.Caret.ScreenPosition;
}

View file

@ -25,9 +25,9 @@ namespace ICSharpCode.TextEditor.Util
Font font,
string countMessage,
string description,
int param_num, bool addit_info)
int param_num, int paramsCount, bool addit_info)
{
GetToolipParts(description, param_num, out var basicDescription, out var documentation, out var bold_beg, out var bold_len);
GetToolipParts(description, param_num, paramsCount, out var basicDescription, out var documentation, out var bold_beg, out var bold_len);
return GetDrawingSizeDrawHelpTip(control, graphics, font, countMessage, basicDescription, documentation, bold_beg, bold_len, param_num, addit_info);
}
@ -36,16 +36,16 @@ namespace ICSharpCode.TextEditor.Util
Graphics graphics,
Font font,
string countMessage,
string description, int param_num, bool addit_info)
string description, int param_num, int paramsCount, bool addit_info)
{
GetToolipParts(description, param_num, out var basicDescription, out var documentation, out var bold_beg, out var bold_len);
GetToolipParts(description, param_num, paramsCount, out var basicDescription, out var documentation, out var bold_beg, out var bold_len);
return DrawHelpTip(control, graphics, font, countMessage,
basicDescription, documentation, bold_beg, bold_len, param_num, addit_info);
}
private static void GetToolipParts(string description, int param_num, out string basicDescription, out string documentation, out int bold_beg, out int bold_len)
private static void GetToolipParts(string description, int param_num, int paramsCount, out string basicDescription, out string documentation, out int bold_beg, out int bold_len)
{
basicDescription = null;
documentation = null;
@ -67,14 +67,11 @@ namespace ICSharpCode.TextEditor.Util
if (param_num == -1)
return;
int extensionIndex = basicDescription.IndexOf("(расширение") + 1;
var languageInfo = CodeCompletion.CodeCompletionController.CurrentParser.LanguageInformation;
int startIndex = basicDescription.IndexOf('(') + 1;
int startIndex = basicDescription.IndexOf("(", basicDescription.IndexOf("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION")) + 1) + 1;
if (startIndex != 0 && startIndex == extensionIndex)
startIndex = basicDescription.IndexOf('(', basicDescription.IndexOf(')') + 1) + 1;
int paranthesisIndex = FindClosingParenthesis(basicDescription.Substring(startIndex));
int paranthesisIndex = languageInfo.FindClosingParenthesis(basicDescription.Substring(startIndex), ')');
if (paranthesisIndex == -1)
return;
@ -87,7 +84,7 @@ namespace ICSharpCode.TextEditor.Util
if (bold_beg != 0)
{
int paramDelimIndex = FindParamDelim(basicDescription.Substring(bold_beg), 1);
int paramDelimIndex = languageInfo.FindParamDelim(basicDescription.Substring(bold_beg), 1);
if (paramDelimIndex == -1)
{
@ -101,22 +98,56 @@ namespace ICSharpCode.TextEditor.Util
}
else
{
string paramDelim = CodeCompletion.CodeCompletionController.CurrentParser.LanguageInformation.ParameterDelimiter;
int paramDelimIndex = FindParamDelim(basicDescription.Substring(startIndex), param_num - 1);
if (paramDelimIndex != -1)
// Здесь учтется случай последнего параметра типа params EVA
if (param_num > paramsCount)
{
bold_beg = paramDelimIndex + startIndex + paramDelim.Length;
int secondParamDelimIndex = FindParamDelim(basicDescription.Substring(startIndex), param_num);
if (secondParamDelimIndex == -1)
if (paramsCount == 1)
{
bold_len = end_sk - bold_beg;
string paramDescription = basicDescription.Substring(startIndex, paranthesisIndex);
if (languageInfo.IsParams(paramDescription))
{
bold_beg = startIndex;
bold_len = paranthesisIndex;
}
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
string descriptionAfterBracket = basicDescription.Substring(startIndex);
int paramDelimIndex = languageInfo.FindParamDelim(descriptionAfterBracket, paramsCount - 1);
if (paramDelimIndex != -1)
{
int paramDelimLength = languageInfo.ParameterDelimiter.Length;
string paramDescription = descriptionAfterBracket.Substring(paramDelimIndex + paramDelimLength, paranthesisIndex - paramDelimIndex - paramDelimLength);
if (languageInfo.IsParams(paramDescription))
{
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
bold_len = end_sk - bold_beg;
}
}
}
}
else
{
int paramDelimIndex = languageInfo.FindParamDelim(basicDescription.Substring(startIndex), param_num - 1);
if (paramDelimIndex != -1)
{
bold_beg = paramDelimIndex + startIndex + languageInfo.ParameterDelimiter.Length;
int secondParamDelimIndex = languageInfo.FindParamDelim(basicDescription.Substring(startIndex), param_num);
if (secondParamDelimIndex == -1)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
}
}
}
}
@ -515,79 +546,5 @@ namespace ICSharpCode.TextEditor.Util
{
return text != null && text.Length > 0;
}
private static int FindClosingParenthesis(string descriptionAfterOpeningParenthesis)
{
int count = 1;
int i = 0;
foreach (char c in descriptionAfterOpeningParenthesis)
{
if (c == '(')
{
count++;
}
else if (c == ')')
{
count--;
}
if (count == 0)
{
break;
}
i++;
}
return i;
}
private static int FindParamDelim(string descriptionAfterOpeningParenthesis, int number)
{
string paramDelimiter = CodeCompletion.CodeCompletionController.CurrentParser.LanguageInformation.ParameterDelimiter;
int count = 1;
int i = 0;
int delimNum = 0;
foreach (char c in descriptionAfterOpeningParenthesis)
{
if (c == '(' || c == '[' || c == '<' || c == '{')
{
count++;
}
else if (c == ')' || c == ']' || c == '>' || c == '}')
{
count--;
}
if (count == 0)
{
break;
}
// если не внутри внутренних скобок
else if (count == 1)
{
if (descriptionAfterOpeningParenthesis.Substring(i).StartsWith(paramDelimiter))
{
delimNum++;
if (delimNum == number)
break;
}
}
i++;
}
if (delimNum < number || i == descriptionAfterOpeningParenthesis.Length)
return -1;
return i;
}
}
}

View file

@ -26,7 +26,7 @@ namespace ICSharpCode.TextEditor.Gui.CompletionWindow
//pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
if (Description != null && Description.Length > 0) {
if (!in_completion_list)
ICSharpCode.TextEditor.Util.TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, null, Description,-1,false);
ICSharpCode.TextEditor.Util.TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, null, Description,-1, -1, false);
else
{
if (has_tags())

View file

@ -167,15 +167,16 @@ namespace ICSharpCode.TextEditor.Gui.InsightWindow
}
//pe.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
int num_param = (DataProvider as VisualPascalABC.DefaultInsightDataProvider).num_param;
drawingSize = TipPainterTools.GetDrawingSizeHelpTipFromCombinedDescription(this,
int paramsCount = (DataProvider as VisualPascalABC.DefaultInsightDataProvider).param_count;
drawingSize = TipPainterTools.GetDrawingSizeHelpTipFromCombinedDescription(this,
pe.Graphics,
Font,
methodCountMessage,
description,num_param,true);
description,num_param, paramsCount, true);
if (drawingSize != Size) {
SetLocation();
} else {
TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, methodCountMessage, description, num_param,true);
TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, methodCountMessage, description, num_param, paramsCount, true);
}
lastCursorScreenPosition = control.ActiveTextAreaControl.TextArea.Caret.ScreenPosition;
}

View file

@ -25,9 +25,9 @@ namespace ICSharpCode.TextEditor.Util
Font font,
string countMessage,
string description,
int param_num, bool addit_info)
int param_num, int paramsCount, bool addit_info)
{
GetToolipParts(description, param_num, out var basicDescription, out var documentation, out var bold_beg, out var bold_len);
GetToolipParts(description, param_num, paramsCount, out var basicDescription, out var documentation, out var bold_beg, out var bold_len);
return GetDrawingSizeDrawHelpTip(control, graphics, font, countMessage, basicDescription, documentation, bold_beg, bold_len, param_num, addit_info);
}
@ -36,15 +36,15 @@ namespace ICSharpCode.TextEditor.Util
Graphics graphics,
Font font,
string countMessage,
string description, int param_num, bool addit_info)
string description, int param_num, int paramsCount, bool addit_info)
{
GetToolipParts(description, param_num, out var basicDescription, out var documentation, out var bold_beg, out var bold_len);
GetToolipParts(description, param_num, paramsCount, out var basicDescription, out var documentation, out var bold_beg, out var bold_len);
return DrawHelpTip(control, graphics, font, countMessage,
basicDescription, documentation, bold_beg, bold_len, param_num, addit_info);
}
private static void GetToolipParts(string description, int param_num, out string basicDescription, out string documentation, out int bold_beg, out int bold_len)
private static void GetToolipParts(string description, int param_num, int paramsCount, out string basicDescription, out string documentation, out int bold_beg, out int bold_len)
{
basicDescription = null;
documentation = null;
@ -66,14 +66,11 @@ namespace ICSharpCode.TextEditor.Util
if (param_num == -1)
return;
int extensionIndex = basicDescription.IndexOf("(расширение") + 1;
var languageInfo = CodeCompletion.CodeCompletionController.CurrentParser.LanguageInformation;
int startIndex = basicDescription.IndexOf('(') + 1;
int startIndex = basicDescription.IndexOf("(", basicDescription.IndexOf("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION")) + 1) + 1;
if (startIndex != 0 && startIndex == extensionIndex)
startIndex = basicDescription.IndexOf('(', basicDescription.IndexOf(')') + 1) + 1;
int paranthesisIndex = FindClosingParenthesis(basicDescription.Substring(startIndex));
int paranthesisIndex = languageInfo.FindClosingParenthesis(basicDescription.Substring(startIndex), ')');
if (paranthesisIndex == -1)
return;
@ -86,7 +83,7 @@ namespace ICSharpCode.TextEditor.Util
if (bold_beg != 0)
{
int paramDelimIndex = FindParamDelim(basicDescription.Substring(bold_beg), 1);
int paramDelimIndex = languageInfo.FindParamDelim(basicDescription.Substring(bold_beg), 1);
if (paramDelimIndex == -1)
{
@ -100,22 +97,56 @@ namespace ICSharpCode.TextEditor.Util
}
else
{
string paramDelim = CodeCompletion.CodeCompletionController.CurrentParser.LanguageInformation.ParameterDelimiter;
int paramDelimIndex = FindParamDelim(basicDescription.Substring(startIndex), param_num - 1);
if (paramDelimIndex != -1)
// Здесь учтется случай последнего параметра типа params EVA
if (param_num > paramsCount)
{
bold_beg = paramDelimIndex + startIndex + paramDelim.Length;
int secondParamDelimIndex = FindParamDelim(basicDescription.Substring(startIndex), param_num);
if (secondParamDelimIndex == -1)
if (paramsCount == 1)
{
bold_len = end_sk - bold_beg;
string paramDescription = basicDescription.Substring(startIndex, paranthesisIndex);
if (languageInfo.IsParams(paramDescription))
{
bold_beg = startIndex;
bold_len = paranthesisIndex;
}
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
string descriptionAfterBracket = basicDescription.Substring(startIndex);
int paramDelimIndex = languageInfo.FindParamDelim(descriptionAfterBracket, paramsCount - 1);
if (paramDelimIndex != -1)
{
int paramDelimLength = languageInfo.ParameterDelimiter.Length;
string paramDescription = descriptionAfterBracket.Substring(paramDelimIndex + paramDelimLength, paranthesisIndex - paramDelimIndex - paramDelimLength);
if (languageInfo.IsParams(paramDescription))
{
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
bold_len = end_sk - bold_beg;
}
}
}
}
else
{
int paramDelimIndex = languageInfo.FindParamDelim(basicDescription.Substring(startIndex), param_num - 1);
if (paramDelimIndex != -1)
{
bold_beg = paramDelimIndex + startIndex + languageInfo.ParameterDelimiter.Length;
int secondParamDelimIndex = languageInfo.FindParamDelim(basicDescription.Substring(startIndex), param_num);
if (secondParamDelimIndex == -1)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
}
}
}
}
@ -516,79 +547,5 @@ namespace ICSharpCode.TextEditor.Util
{
return text != null && text.Length > 0;
}
private static int FindClosingParenthesis(string descriptionAfterOpeningParenthesis)
{
int count = 1;
int i = 0;
foreach (char c in descriptionAfterOpeningParenthesis)
{
if (c == '(')
{
count++;
}
else if (c == ')')
{
count--;
}
if (count == 0)
{
break;
}
i++;
}
return i;
}
private static int FindParamDelim(string descriptionAfterOpeningParenthesis, int number)
{
string paramDelimiter = CodeCompletion.CodeCompletionController.CurrentParser.LanguageInformation.ParameterDelimiter;
int count = 1;
int i = 0;
int delimNum = 0;
foreach (char c in descriptionAfterOpeningParenthesis)
{
if (c == '(' || c == '[' || c == '<' || c == '{')
{
count++;
}
else if (c == ')' || c == ']' || c == '>' || c == '}')
{
count--;
}
if (count == 0)
{
break;
}
// если не внутри внутренних скобок
else if (count == 1)
{
if (descriptionAfterOpeningParenthesis.Substring(i).StartsWith(paramDelimiter))
{
delimNum++;
if (delimNum == number)
break;
}
}
i++;
}
if (delimNum < number || i == descriptionAfterOpeningParenthesis.Length)
return -1;
return i;
}
}
}