diff --git a/CodeCompletion/DomSyntaxTreeVisitor.cs b/CodeCompletion/DomSyntaxTreeVisitor.cs index 28be778f0..1d8575b62 100644 --- a/CodeCompletion/DomSyntaxTreeVisitor.cs +++ b/CodeCompletion/DomSyntaxTreeVisitor.cs @@ -2246,8 +2246,9 @@ namespace CodeCompletion //(ret_tn as TypeScope).name = _type_declaration.type_name.name; returned_scope.si.name = _type_declaration.type_name.name; returned_scope.si.description = returned_scope.GetDescription(); - if (!(_type_declaration.type_def is class_definition)) - returned_scope.MakeSynonimDescription(); + // Это мертвый код EVA + //if (!(_type_declaration.type_def is class_definition)) + // returned_scope.MakeSynonimDescription(); returned_scope.loc = get_location(_type_declaration);//new location(loc.begin_line_num,loc.begin_column_num,ret_tn.loc.end_line_num,ret_tn.loc.end_column_num,ret_tn.loc.doc); if (_type_declaration.type_def is class_definition) { @@ -2317,7 +2318,8 @@ namespace CodeCompletion cur_scope.AddName(_type_declaration.type_name.name, returned_scope); if (returned_scope is ProcType) { - returned_scope.MakeSynonimDescription(); + ((TypeScope)returned_scope).aliased = true; + returned_scope.BuildDescription(); } location loc = get_location(_type_declaration); if (returned_scope.loc == null) diff --git a/CodeCompletion/SymTable.cs b/CodeCompletion/SymTable.cs index 01edb6484..d5586f952 100644 --- a/CodeCompletion/SymTable.cs +++ b/CodeCompletion/SymTable.cs @@ -587,11 +587,6 @@ namespace CodeCompletion return ""; } - public virtual void MakeSynonimDescription() - { - - } - public virtual string GetDescriptionWithoutDoc() { return si.name; @@ -2608,13 +2603,6 @@ namespace CodeCompletion return is_constructor; } - // не используется нигде для ProcScope EVA - public override void MakeSynonimDescription() - { - //aliased = true; - si.description = CodeCompletionController.CurrentParser?.LanguageInformation.GetSynonimDescription(this); - } - //zavershenie opisanija, vyzyvaetsja kogda parametry razobrany public void Complete() { @@ -4265,11 +4253,20 @@ namespace CodeCompletion this.exact = exact; } + private static string GetDescription(TypeScope t) + { + if (t.Description != null) + return t.Description; + + t.BuildDescription(); + return t.Description; + } + private struct ScopeComparer : IEqualityComparer { public bool Equals(TypeScope t1, TypeScope t2) => t1.IsEqual(t2); - public int GetHashCode(TypeScope t) => t.GetDescription().GetHashCode(); + public int GetHashCode(TypeScope t) => GetDescription(t).GetHashCode(); } public bool Equals(InstanceCreationContext otherInfo) @@ -4282,8 +4279,8 @@ namespace CodeCompletion public override int GetHashCode() { - return string.Join("", genericArguments.Select(arg => arg.si != null ? arg.GetDescription() : "") - .Concat(new string[] { originalType.GetDescription(), exact.ToString() })).GetHashCode(); + return string.Join("", genericArguments.Select(arg => arg.si != null ? GetDescription(arg) : "") + .Concat(new string[] { GetDescription(originalType), exact.ToString() })).GetHashCode(); } } @@ -4817,12 +4814,6 @@ namespace CodeCompletion implemented_interfaces.Add(type); } - public override void MakeSynonimDescription() - { - aliased = true; - si.description = CodeCompletionController.CurrentParser.LanguageInformation.GetSynonimDescription(this); - } - public virtual bool IsConvertable(TypeScope ts, bool strong = false) { if (IsEqual(ts)) @@ -4938,6 +4929,10 @@ namespace CodeCompletion public override void BuildDescription() { si.description = CodeCompletionController.CurrentParser.LanguageInformation.GetDescription(this); + + // Случай делегата + if (aliased && this is ProcType) + si.description = CodeCompletionController.CurrentParser.LanguageInformation.GetSynonimDescription(this); } //opisanie, vysvechivaetsja v zheltkom okoshke diff --git a/ParserTools/ParserTools/BaseLanguageInformation.cs b/ParserTools/ParserTools/BaseLanguageInformation.cs index ed7d7d2e5..515bf04c2 100644 --- a/ParserTools/ParserTools/BaseLanguageInformation.cs +++ b/ParserTools/ParserTools/BaseLanguageInformation.cs @@ -1703,6 +1703,10 @@ namespace PascalABCCompiler.Parsers { keyword = KeywordKind.Raise; } + else if (KeywordsStorage.KeywordsTreatedAsFunctions.Contains(s)) + { + keyword = KeywordKind.None; + } else if (IsKeyword(s)) { keyword = KeywordKind.CommonKeyword; diff --git a/ParserTools/ParserTools/Keywords/BaseKeywords.cs b/ParserTools/ParserTools/Keywords/BaseKeywords.cs index 759ea58ac..cdca3d8d9 100644 --- a/ParserTools/ParserTools/Keywords/BaseKeywords.cs +++ b/ParserTools/ParserTools/Keywords/BaseKeywords.cs @@ -34,6 +34,11 @@ namespace PascalABCCompiler.Parsers /// public List TypeKeywords { get; set; } = new List(); + /// + /// Ключевые слова, которые должны восприниматься как функции при парсинге выражений + /// + public HashSet KeywordsTreatedAsFunctions { get; set; } + /// /// Словарь соответствий ключевых слов их эквивалентам (задается пользователем в специальном файле) /// @@ -83,6 +88,8 @@ namespace PascalABCCompiler.Parsers KeywordsForIntellisenseSet = new HashSet(stringComparer); + KeywordsTreatedAsFunctions = new HashSet(stringComparer); + KeywordKinds = new Dictionary(stringComparer); } @@ -102,7 +109,8 @@ namespace PascalABCCompiler.Parsers return GetIdToken(); } - public void CreateNewKeyword(string name, Enum token = null, KeywordKind kind = KeywordKind.None, bool isTypeKeyword = false, bool excludedInIntellisense = false) + public void CreateNewKeyword(string name, Enum token = null, KeywordKind kind = KeywordKind.None, + bool isTypeKeyword = false, bool excludedInIntellisense = false, bool treatAsFunction = false) { name = ConvertKeyword(name); @@ -115,6 +123,9 @@ namespace PascalABCCompiler.Parsers KeywordsForIntellisenseSet.Add(name); } + if (treatAsFunction) + KeywordsTreatedAsFunctions.Add(name); + // token null может передаваться, если это ключевое слово исключительно для Intellisense (например, break) if (token != null) KeywordsToTokens[name] = (int)(object)token; diff --git a/Parsers/PascalABCParserNewSaushkin/Keywords.cs b/Parsers/PascalABCParserNewSaushkin/Keywords.cs index 6d6894c73..03a4e1522 100644 --- a/Parsers/PascalABCParserNewSaushkin/Keywords.cs +++ b/Parsers/PascalABCParserNewSaushkin/Keywords.cs @@ -26,8 +26,8 @@ namespace Languages.Pascal.Frontend.Core CreateNewKeyword("is", Tokens.tkIs); CreateNewKeyword("implicit", Tokens.tkImplicit); CreateNewKeyword("explicit", Tokens.tkExplicit); - CreateNewKeyword("sizeof", Tokens.tkSizeOf); - CreateNewKeyword("typeof", Tokens.tkTypeOf); + CreateNewKeyword("sizeof", Tokens.tkSizeOf, treatAsFunction: true); + CreateNewKeyword("typeof", Tokens.tkTypeOf, treatAsFunction: true); CreateNewKeyword("where", Tokens.tkWhere); CreateNewKeyword("array", Tokens.tkArray, isTypeKeyword: true); CreateNewKeyword("begin", Tokens.tkBegin); diff --git a/TestSuite/intellisense_tests/extensionmethods8.pas b/TestSuite/intellisense_tests/extensionmethods8.pas index 89df39d96..81f9ba24a 100644 --- a/TestSuite/intellisense_tests/extensionmethods8.pas +++ b/TestSuite/intellisense_tests/extensionmethods8.pas @@ -2,5 +2,5 @@ var ch: char; var n: integer; (ch*n).Replace{@function string.Replace(oldChar: char; newChar: char): string;@}(#0,#32); - (2+3).Between{@(расширение) function integer.Between(a: integer; b: integer): boolean;@}(2,3); + (2+3).Between{@(расширение) function integer.Between(a: integer; b: integer; inclusive: boolean:=True): boolean;@}(2,3); end. \ No newline at end of file