From fa420a349b38f840de445c0b2fb0bc1f49724910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=BD=D0=B4=D0=B0=D1=80=D0=B5=D0=B2=20=D0=98?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD?= Date: Wed, 25 Dec 2019 13:17:32 +0100 Subject: [PATCH] fix pascalabcnet/pascalabcnetide#4 --- CodeCompletion/DomSyntaxTreeVisitor.cs | 2 +- CodeCompletion/ExpressionVisitor.cs | 26 +++++++++++++-- CodeCompletion/SymTable.cs | 15 +++++++++ CodeCompletion/Testing.cs | 36 +++++++++++++++++++++ TestSuite/intellisense_tests/delegates4.pas | 9 ++++++ TestSuite/intellisense_tests/function1.pas | 3 +- TestSuite/intellisense_tests/generics2.pas | 2 +- 7 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 TestSuite/intellisense_tests/delegates4.pas diff --git a/CodeCompletion/DomSyntaxTreeVisitor.cs b/CodeCompletion/DomSyntaxTreeVisitor.cs index 8b2571fd6..7a793a8f6 100644 --- a/CodeCompletion/DomSyntaxTreeVisitor.cs +++ b/CodeCompletion/DomSyntaxTreeVisitor.cs @@ -5315,7 +5315,7 @@ namespace CodeCompletion if (awaitedProcType != null) { if (awaitedProcType is TypeSynonim) - awaitedProcType = (awaitedProcType as TypeSynonim).actType; + awaitedProcType = (awaitedProcType as TypeSynonim).GetLeafActType(); if (awaitedProcType is ProcType) { if ((awaitedProcType as ProcType).target.parameters.Count > 0) diff --git a/CodeCompletion/ExpressionVisitor.cs b/CodeCompletion/ExpressionVisitor.cs index 135b1767f..61f0d0c09 100644 --- a/CodeCompletion/ExpressionVisitor.cs +++ b/CodeCompletion/ExpressionVisitor.cs @@ -167,7 +167,7 @@ namespace CodeCompletion { if (!((returned_scopes[i] as ProcScope).is_constructor && returned_scopes[i].is_static)) proces.Add(returned_scopes[i] as ProcScope); - } + } else if (returned_scopes[i] is ElementScope && (returned_scopes[i] as ElementScope).sc is CompiledScope) { //ProcType pt = new ProcType(); @@ -176,6 +176,28 @@ namespace CodeCompletion if (ps != null) proces.Add(ps); } + else if (returned_scopes[i] is ElementScope && (returned_scopes[i] as ElementScope).sc is TypeSynonim) + { + TypeSynonim ts = (returned_scopes[i] as ElementScope).sc as TypeSynonim; + TypeScope act_ts = ts.GetLeafActType(); + ProcType procType =act_ts as ProcType; + if (procType != null) + { + ProcScope tmp = procType.target; + if (tmp != null) + proces.Add(tmp); + } + else + { + CompiledScope cs = act_ts as CompiledScope; + if (cs != null) + { + ProcScope ps = cs.FindNameOnlyInThisType("Invoke") as ProcScope; + if (ps != null) + proces.Add(ps); + } + } + } else if (i == 0) return proces; } @@ -1099,7 +1121,7 @@ namespace CodeCompletion _method_call.dereferencing_value.visit(this); search_all = false; SymScope[] names = returned_scopes.ToArray(); - if (names.Length > 0 && names[0] is ElementScope && ((names[0] as ElementScope).sc is ProcType || (names[0] as ElementScope).sc is CompiledScope)) + if (names.Length > 0 && names[0] is ElementScope && (names[0] as ElementScope).sc is TypeScope && ((names[0] as ElementScope).sc as TypeScope).IsDelegate) { returned_scope = names[0]; return; diff --git a/CodeCompletion/SymTable.cs b/CodeCompletion/SymTable.cs index fac839d57..dc4ffb507 100644 --- a/CodeCompletion/SymTable.cs +++ b/CodeCompletion/SymTable.cs @@ -3012,6 +3012,13 @@ namespace CodeCompletion } } + public TypeScope GetLeafActType(int level=0) + { + if (actType is TypeSynonim && level < 10) + return (actType as TypeSynonim).GetLeafActType(level+1); + return actType; + } + public override SymInfo[] GetNames() { //SortedDictionary dict = new SortedDictionary(); @@ -3082,6 +3089,14 @@ namespace CodeCompletion } } + public override bool IsDelegate + { + get + { + return actType.IsDelegate; + } + } + public override void AddIndexer(TypeScope ts, bool is_static) { actType.AddIndexer(ts, is_static); diff --git a/CodeCompletion/Testing.cs b/CodeCompletion/Testing.cs index 8c3e507b1..5772efb7a 100644 --- a/CodeCompletion/Testing.cs +++ b/CodeCompletion/Testing.cs @@ -75,6 +75,23 @@ namespace CodeCompletion tmp = tmp.Remove(ind, tmp.IndexOf("]}") + 2 - ind); ind = tmp.IndexOf("{["); } + + ind = tmp.IndexOf("{("); + while (ind != -1) + { + var lines = tmp.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.None); + var pos = ind - 1; + var line = GetLineByPos(lines, pos); + var col = GetColByPos(lines, pos); + var desc = CodeCompletion.CodeCompletionTester.GetMethodDescription(pos, tmp, line, col, FileName, dc, comp.ParsersController, 1, 1); + var should_desc = tmp.Substring(ind + 2, tmp.IndexOf(")}") - ind - 2); + if (desc == null) + desc = ""; + desc = desc.Split(new string[] { "\n" }, StringSplitOptions.None)[0].Trim(); + assert(desc.Replace(", ", ",") == should_desc.Replace(", ", ","), FileName + ", should: " + should_desc + ", is: " + desc); + tmp = tmp.Remove(ind, tmp.IndexOf(")}") + 2 - ind); + ind = tmp.IndexOf("{("); + } } } @@ -144,6 +161,25 @@ namespace CodeCompletion return ""; } + public static string GetMethodDescription(int pos, string content, int line, int col, string FileName, DomConverter dc, PascalABCCompiler.Parsers.Controller controller, + int num_param, int cur_param_num) + { + string expr_without_brackets = null; + PascalABCCompiler.Parsers.KeywordKind keyw; + var expr = CodeCompletion.CodeCompletionController.CurrentParser.LanguageInformation.FindExpressionFromAnyPosition(pos, content, line, col, out keyw, out expr_without_brackets); + if (expr == null) + expr = expr_without_brackets; + var errors = new List(); + var warnings = new List(); + var tree = controller.GetExpression("test" + Path.GetExtension(FileName), expr, errors, warnings); + int defaultIndex = 0; + int param_count = 0; + var desc = dc.GetNameOfMethod(tree, expr, line, col, num_param, ref defaultIndex, cur_param_num, out param_count); + if (desc != null && desc.Length > 0) + return desc[0]; + return ""; + } + private static void assert(bool cond, string message=null) { if (message != null) diff --git a/TestSuite/intellisense_tests/delegates4.pas b/TestSuite/intellisense_tests/delegates4.pas new file mode 100644 index 000000000..0e6c95ee4 --- /dev/null +++ b/TestSuite/intellisense_tests/delegates4.pas @@ -0,0 +1,9 @@ +type + T = byte -> (); + +var p: T; + +begin + if p <> nil then p{@var p: T;@}(2); + p{(procedure Action<>.Invoke(obj: byte); virtual;)}(2); +end. \ No newline at end of file diff --git a/TestSuite/intellisense_tests/function1.pas b/TestSuite/intellisense_tests/function1.pas index d7a1b8d0f..79cc70feb 100644 --- a/TestSuite/intellisense_tests/function1.pas +++ b/TestSuite/intellisense_tests/function1.pas @@ -1,4 +1,4 @@ -function Test(a: integer): integer; +function Test(a: integer): integer; begin end; @@ -29,6 +29,7 @@ begin Test{@function Test(a: string): integer;@}('333'); Test{@function Test(a: boolean): integer;@}(true); Test{@function Test(a: List): integer;@}(Lst(2,3,4)); + Test{(function Test(a: integer): integer;)}; var delim: array of char; 'aa'.Split{@function string.Split(separator: array of char; options: StringSplitOptions): array of string;@}(delim, System.StringSplitOptions.RemoveEmptyEntries); end. \ No newline at end of file diff --git a/TestSuite/intellisense_tests/generics2.pas b/TestSuite/intellisense_tests/generics2.pas index 965d2876b..d4d5ac010 100644 --- a/TestSuite/intellisense_tests/generics2.pas +++ b/TestSuite/intellisense_tests/generics2.pas @@ -1,4 +1,4 @@ -function f1{(a: byte)}: (T1, T2, T3);begin end; +function f1: (T1, T2, T3);begin end; function f2(a: byte): (T1, T2, T3);begin end; begin var a{@var a: (byte,word,single);@} := f1&;