From 6fa1caa034071116bd6bf984b6ec41a0e1fa85d2 Mon Sep 17 00:00:00 2001 From: AlexanderZemlyak <92867056+AlexanderZemlyak@users.noreply.github.com> Date: Sat, 5 Jul 2025 11:05:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D1=87=D0=B5=D1=82=20=D1=81=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D0=B0=D1=8F=20params=20=D0=B2=20TipPainterTools=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=BF=D0=BE=D0=B4=D1=81=D0=B2=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=B5=20(#3318)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor LanguageInformation classes * Improve extension check in TipPainterTools * Refactor parsing parameters for signature help * Fix TipPainterTools Linux version * Add Params check in TipPainterTools --- CodeCompletion/SymTable.cs | 3 +- .../SPythonLanguageInformation.cs | 9 + .../ParserTools/BaseLanguageInformation.cs | 224 +++++++++++++++++- .../ParserTools/ILanguageInformation.cs | 12 + .../PascalABCLanguageInformation.cs | 148 +----------- .../CodeCompletionVisual/DeclarationWindow.cs | 2 +- .../DS/CodeCompletionVisual/InsightWindow.cs | 7 +- .../CodeCompletionVisual/TipPainterTools.cs | 151 +++++------- .../CodeCompletionVisual/DeclarationWindow.cs | 2 +- .../DS/CodeCompletionVisual/InsightWindow.cs | 7 +- .../CodeCompletionVisual/TipPainterTools.cs | 151 +++++------- 11 files changed, 370 insertions(+), 346 deletions(-) diff --git a/CodeCompletion/SymTable.cs b/CodeCompletion/SymTable.cs index eb391b4fd..fd319339f 100644 --- a/CodeCompletion/SymTable.cs +++ b/CodeCompletion/SymTable.cs @@ -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); diff --git a/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInformation.cs b/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInformation.cs index 8e46912d8..ef8f595fe 100644 --- a/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInformation.cs +++ b/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInformation.cs @@ -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 renamings = new Dictionary { ["biginteger"] = "bigint" diff --git a/ParserTools/ParserTools/BaseLanguageInformation.cs b/ParserTools/ParserTools/BaseLanguageInformation.cs index 6e5dea24c..a13f9cc76 100644 --- a/ParserTools/ParserTools/BaseLanguageInformation.cs +++ b/ParserTools/ParserTools/BaseLanguageInformation.cs @@ -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 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'); + }*/ + 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; + } } } diff --git a/ParserTools/ParserTools/ILanguageInformation.cs b/ParserTools/ParserTools/ILanguageInformation.cs index 794d0331c..ada2013e4 100644 --- a/ParserTools/ParserTools/ILanguageInformation.cs +++ b/ParserTools/ParserTools/ILanguageInformation.cs @@ -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 SpecialModulesAliases { get; } BaseKeywords KeywordsStorage @@ -156,6 +164,10 @@ namespace PascalABCCompiler.Parsers { get; } + string DelimiterInIndexer + { + get; + } string ResultVariableName { get; diff --git a/PascalABCLanguageInfo/PascalABCLanguageInformation.cs b/PascalABCLanguageInfo/PascalABCLanguageInformation.cs index d8134be11..9a07f744a 100644 --- a/PascalABCLanguageInfo/PascalABCLanguageInformation.cs +++ b/PascalABCLanguageInfo/PascalABCLanguageInformation.cs @@ -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'); - }*/ - 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; diff --git a/VisualPascalABCNET/DS/CodeCompletionVisual/DeclarationWindow.cs b/VisualPascalABCNET/DS/CodeCompletionVisual/DeclarationWindow.cs index a6d0fa2de..691fc1b13 100644 --- a/VisualPascalABCNET/DS/CodeCompletionVisual/DeclarationWindow.cs +++ b/VisualPascalABCNET/DS/CodeCompletionVisual/DeclarationWindow.cs @@ -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()) diff --git a/VisualPascalABCNET/DS/CodeCompletionVisual/InsightWindow.cs b/VisualPascalABCNET/DS/CodeCompletionVisual/InsightWindow.cs index febc4c432..22c01d0f3 100644 --- a/VisualPascalABCNET/DS/CodeCompletionVisual/InsightWindow.cs +++ b/VisualPascalABCNET/DS/CodeCompletionVisual/InsightWindow.cs @@ -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; } diff --git a/VisualPascalABCNET/DS/CodeCompletionVisual/TipPainterTools.cs b/VisualPascalABCNET/DS/CodeCompletionVisual/TipPainterTools.cs index 9533b3464..faddc1a84 100644 --- a/VisualPascalABCNET/DS/CodeCompletionVisual/TipPainterTools.cs +++ b/VisualPascalABCNET/DS/CodeCompletionVisual/TipPainterTools.cs @@ -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; - } } } diff --git a/VisualPascalABCNETLinux/DS/CodeCompletionVisual/DeclarationWindow.cs b/VisualPascalABCNETLinux/DS/CodeCompletionVisual/DeclarationWindow.cs index a6d0fa2de..691fc1b13 100644 --- a/VisualPascalABCNETLinux/DS/CodeCompletionVisual/DeclarationWindow.cs +++ b/VisualPascalABCNETLinux/DS/CodeCompletionVisual/DeclarationWindow.cs @@ -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()) diff --git a/VisualPascalABCNETLinux/DS/CodeCompletionVisual/InsightWindow.cs b/VisualPascalABCNETLinux/DS/CodeCompletionVisual/InsightWindow.cs index 91732b54b..bab5389c9 100644 --- a/VisualPascalABCNETLinux/DS/CodeCompletionVisual/InsightWindow.cs +++ b/VisualPascalABCNETLinux/DS/CodeCompletionVisual/InsightWindow.cs @@ -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; } diff --git a/VisualPascalABCNETLinux/DS/CodeCompletionVisual/TipPainterTools.cs b/VisualPascalABCNETLinux/DS/CodeCompletionVisual/TipPainterTools.cs index de60ce0cb..c181efcc2 100644 --- a/VisualPascalABCNETLinux/DS/CodeCompletionVisual/TipPainterTools.cs +++ b/VisualPascalABCNETLinux/DS/CodeCompletionVisual/TipPainterTools.cs @@ -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; - } } }