From 96df3ed752f28747fdff7df0ae98647e340350e5 Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Sun, 12 Dec 2021 11:53:50 +0100 Subject: [PATCH] fix pascalabcnet/pascalabcnetide#232 --- CodeCompletion/DomSyntaxTreeVisitor.cs | 51 +++++++++++++++++---- CodeCompletion/SymTable.cs | 19 ++++++++ TestSuite/intellisense_tests/autoclass4.pas | 5 +- TestSuite/intellisense_tests/delegates5.pas | 9 ++++ TestSuite/intellisense_tests/foreach6.pas | 1 + 5 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 TestSuite/intellisense_tests/delegates5.pas diff --git a/CodeCompletion/DomSyntaxTreeVisitor.cs b/CodeCompletion/DomSyntaxTreeVisitor.cs index 19bc3e575..078da2cdb 100644 --- a/CodeCompletion/DomSyntaxTreeVisitor.cs +++ b/CodeCompletion/DomSyntaxTreeVisitor.cs @@ -82,7 +82,7 @@ namespace CodeCompletion } } - private named_type_reference BuildSyntaxNodeForTypeReference(type_node tn) + private type_definition BuildSyntaxNodeForTypeReference(type_node tn) { if (tn.instance_params != null && tn.instance_params.Count > 0) { @@ -110,13 +110,13 @@ namespace CodeCompletion tmp.AddName(gen_td.PrintableName, cur_scope); ts.loc = get_location(gen_td.location); ts.si = new SymInfo("class", SymbolKind.Class, ""); - foreach (var field in (gen_td as common_type_node).fields) + foreach (var prop in (gen_td as common_type_node).properties) { ElementScope es = new ElementScope(); - es.si = new SymInfo(field.name, SymbolKind.Property, ""); - BuildSyntaxNodeForTypeReference(field.type).visit(this); + es.si = new SymInfo(prop.name, SymbolKind.Property, ""); + BuildSyntaxNodeForTypeReference(prop.property_type).visit(this); es.sc = returned_scope; - ts.AddName(field.name, es); + ts.AddName(prop.name, es); } returned_scope = cur_scope; cur_scope = tmp; @@ -135,6 +135,31 @@ namespace CodeCompletion var ntr = new named_type_reference(); if (tn.IsDelegate) { + var invokeMeth = tn.find_first_in_type("Invoke"); + if (invokeMeth != null) + { + var fn = invokeMeth.sym_info as function_node; + procedure_header header; + if (fn.return_value_type != null) + { + header = new function_header(BuildSyntaxNodeForTypeReference(fn.return_value_type)); + } + else + { + header = new procedure_header(); + } + header.parameters = new formal_parameters(); + foreach (var param in fn.parameters) + { + var tparam = new typed_parameters(); + tparam.vars_type = BuildSyntaxNodeForTypeReference(param.type); + tparam.idents = new ident_list(); + tparam.idents.Add(new ident(param.name)); + header.parameters.Add(tparam); + + } + return header; + } ntr.names.Add(new ident(tn.PrintableName.Replace("()", ""))); return ntr; } @@ -202,7 +227,7 @@ namespace CodeCompletion else { - if (tn.full_name.IndexOf("$") != -1 || tn.full_name.IndexOf("#") != -1 && tn.full_name.IndexOf("AnonymousType#") == -1) + if (tn.full_name.IndexOf("$") != -1 && !tn.IsDelegate|| tn.full_name.IndexOf("#") != -1 && tn.full_name.IndexOf("AnonymousType#") == -1) return ts; if (ts is FileScope && tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.typed_file) return ts; @@ -213,7 +238,17 @@ namespace CodeCompletion ntr.visit(this); if (returned_scope != null && returned_scope is TypeScope) - return returned_scope as TypeScope; + { + var correctedType = returned_scope as TypeScope; + if (!correctedType.IsTypeStrictEqual(ts)) + return correctedType; + } + else if (returned_scope != null && returned_scope is ProcScope) + { + var procType = new ProcType(returned_scope as ProcScope); + if (!procType.IsEqual(ts)) + return procType; + } return ts; } } @@ -269,13 +304,11 @@ namespace CodeCompletion co.SourceFileName = cu.source_context.FileName; co.ForIntellisense = true; co.SaveDocumentation = false; - //if (compiler == null) compiler = new Compiler(); compiler.CompilerOptions = co; compiler.ClearAfterCompilation = false; compiler.Compile(); - foreach (var lv in compiler.CompiledVariables) CorrectVariableType(lv); compiler.ClearAll(/*false*/); diff --git a/CodeCompletion/SymTable.cs b/CodeCompletion/SymTable.cs index 2e5625ba4..0da4bb374 100644 --- a/CodeCompletion/SymTable.cs +++ b/CodeCompletion/SymTable.cs @@ -4606,6 +4606,25 @@ namespace CodeCompletion return false; } + public virtual bool IsTypeStrictEqual(TypeScope ts) + { + var eq = this.IsEqual(ts); + if (!eq) + return false; + if (this.instances != null && ts.instances == null) + return false; + if (this.instances == null && ts.instances != null) + return false; + if (this.instances.Count != ts.instances.Count) + return false; + for (int i = 0; i < this.instances.Count; i++) + { + if (!this.instances[i].IsTypeStrictEqual(ts.instances[i])) + return false; + } + return true; + } + public virtual ProcScope GetConstructor() { foreach (SymScope ss in members) diff --git a/TestSuite/intellisense_tests/autoclass4.pas b/TestSuite/intellisense_tests/autoclass4.pas index 47528dfbe..1adab9659 100644 --- a/TestSuite/intellisense_tests/autoclass4.pas +++ b/TestSuite/intellisense_tests/autoclass4.pas @@ -1,3 +1,6 @@ ### var a{@var a: sequence of class;@} := (1..18).Sel(i->new class(f := i, g := i.ToS)); -var x{@var x: string;@} := a.First().g; \ No newline at end of file +var x{@var x: string;@} := a.First.g; +var y{@var y: class;@} := a.First; +writeln(a.First.g{@property class.g: string;@}); + diff --git a/TestSuite/intellisense_tests/delegates5.pas b/TestSuite/intellisense_tests/delegates5.pas new file mode 100644 index 000000000..57d3384ff --- /dev/null +++ b/TestSuite/intellisense_tests/delegates5.pas @@ -0,0 +1,9 @@ +type + a = class + static function fun(x: integer): integer; + begin end; + end; + +begin + var p{@var p: function(x: integer): integer;@}:= a.fun; +end. \ No newline at end of file diff --git a/TestSuite/intellisense_tests/foreach6.pas b/TestSuite/intellisense_tests/foreach6.pas index 4d14e9cfe..45811468e 100644 --- a/TestSuite/intellisense_tests/foreach6.pas +++ b/TestSuite/intellisense_tests/foreach6.pas @@ -4,4 +4,5 @@ begin var coll: system.windows.forms.ListBox.SelectedIndexCollection; foreach var a in coll do a{@var a: Object;@}.IsEven.print; + end. \ No newline at end of file