pascalabcnet/CodeCompletion/DomConverter.cs
AlexanderZemlyak 69149f8c44
Refactor intellisense (#3213)
* Refactor keywords managing to avoid repeating them twice

* Fix build error

* Fix string comparisons and null reference exception

* Manage references in PascalABCLanguageInfo project

* Fix inaccuracy in BaseKeywords.cs

* Move ValidDirectives field to ILanguageInformation

* Basic refactoring of GetPopupHintText + delete ampersend inserting

* Delete other cases of ampersend inserting

* Add check that we parsing PascalABC.NET in GetPopupHintText

Временное решение, нужно будет вынести вторую попытку в интерфейс парсера.

* Refactor CodeCompletionProvider (first iteration)

* Extract shift space actions in separate class

* Replace dollar service character in CodeCompletion by separate boolean (ctrlSpaceAfterDot))

* Refactor GetCompletionDataByFirst method

* Fix GetCompletionDataByFirst behaviour when getting symInfos after uses keyword

* Another iteration of refactoring in CodeCompletionProvider + comments

* Update intellisense documentation

* Fix build error

* Fix encoding

* Squashed commit of the following:

commit 7751fe7e75
Author: samuraiGH <87191377+samuraiGH@users.noreply.github.com>
Date:   Sun Mar 16 13:28:03 2025 +0300

    generating language res file at build time (#3252)

commit d1fce63d69
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Mar 4 08:38:09 2025 +0300

    Сборка после pr SDK

commit d491e88aa7
Author: samuraiGH <87191377+samuraiGH@users.noreply.github.com>
Date:   Mon Mar 3 20:34:51 2025 +0300

    migration to new build system (#3241)

    * converting project files into sdk style
    * new build commands
    * adding new dll into nsis
    * removing unused .cs files

commit 1fd348ec3c
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sun Feb 23 20:49:26 2025 +0300

    NSIS New 3.10

    Ярлык в меню Пуск у всех пользователей

commit 80b7182dc1
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Feb 19 11:50:00 2025 +0300

    _ in names

commit a2b078960b
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Feb 19 10:52:25 2025 +0300

    cnfc2

commit 58f26d469d
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Feb 18 22:28:13 2025 +0300

    перекомпиляция 3.10.3.3611

commit b78a72977f
Author: nevermind322 <81963698+nevermind322@users.noreply.github.com>
Date:   Tue Feb 18 22:02:19 2025 +0300

    fix build on mono (#3249)

    * fix build on mono

    * remove local func

    * fix again

commit c3557e388c
Author: Nikolay Kuznetsov <adasoft@gmail.com>
Date:   Sat Feb 15 20:32:46 2025 +0300

    Update GraphABC.pas (#3244)

    1. Быстрая реализация функции FloodFill
    Для этого добавлена процедура BitmapFloodFill, которая вызывается из метода Picture.FloodFill и процедуры FloodFill

    2.Добавлена поддержка LockDrawing/UnlockDrawing в процедуру FloodFill

commit 9dbac389e1
Author: AlexanderZemlyak <92867056+AlexanderZemlyak@users.noreply.github.com>
Date:   Wed Feb 12 13:57:14 2025 +0300

    Add missing projects to pabcnetc.sln (#3247)

commit 41dfb6f187
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Fri Feb 7 21:41:01 2025 +0300

    [] - преобразование во все контейнеры

    GraphABCHelper - теперь ABCObjects работает под Линукс

    School исправлен согласно последним веяниям []

commit 79bbbd10ff
Author: samuraiGH <87191377+samuraiGH@users.noreply.github.com>
Date:   Wed Jan 29 20:18:37 2025 +0300

    removing files for support fx4.0 (#3240)

commit 88d5c409eb
Author: samuraiGH <87191377+samuraiGH@users.noreply.github.com>
Date:   Tue Jan 28 20:41:55 2025 +0300

    Рефакторинг PascalABCNET.xshd (#3237)

    * refactoring PascalABCNET.xshd

    * removing extra characters

commit 8fbd7fdfc3
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sun Jan 26 23:42:48 2025 +0300

    3.10.3
    faststrings
    EmptyCollection и преобразование ее в List, Dictionary
    t: (real,real) := (1,2)

commit bba132bd5d
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Jan 22 09:14:44 2025 +0300

    Поправил справку по функции

commit 1bd21857cc
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Jan 8 18:46:51 2025 +0300

    Teacher Control Plugin - возможность задать server.dat

commit 0848a1b796
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Jan 4 22:54:38 2025 +0300

    Исправление автоформатирования []

commit d45b782a7b
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Jan 4 18:45:07 2025 +0300

    Rename PABCSistem in test suite

commit c2347e604b
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Jan 4 14:44:51 2025 +0300

    Примеры - устранил неточности

    LightPT - имя сервера вынес в публичную секцию

commit b68b8da970
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 17 15:52:18 2024 +0300

    Примеры Coords1.pas Coords2.pas.pas

commit 8a9788e6f9
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 17 15:06:57 2024 +0300

    Перенес проверку set array на уровень парсера

    Немного поправил Intellisense по наведению для NewSet

    По точке там что то другое работает

commit 874ddebad3
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Dec 14 21:00:38 2024 +0300

    Поправил грамматику []

    Теперь нельзя в режиме ## использовать атрибуты

    Зато можно [1,2,3].Print

commit 080fb487e1
Merge: a53dcd9ed a484b0e82
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Dec 14 15:25:24 2024 +0300

    Merge branch 'master' of https://github.com/pascalabcnet/pascalabcnet

commit a53dcd9ed2
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Dec 14 15:25:16 2024 +0300

    SF Prm Cmb для строк

commit a484b0e82d
Author: Sun Serega <sunserega2@gmail.com>
Date:   Thu Dec 12 13:49:17 2024 +0200

    fix (#3231)

commit 6ef11f249c
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 10 11:05:45 2024 +0300

    3.10.2

commit db9679d89f
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 10 10:59:20 2024 +0300

    Закончил превращение синтаксиса [] по умолчанию в массивы

commit 45fdde24b4
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Sun Dec 8 18:08:00 2024 +0100

    #3229

commit 494b47624d
Merge: 5875b9929 7906d73da
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Sun Dec 8 10:42:07 2024 +0100

    Merge branch 'master' of https://github.com/pascalabcnet/pascalabcnet

commit 5875b99296
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Sun Dec 8 10:41:53 2024 +0100

    platformtarget native - .NET 9.0

commit 7906d73da3
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 3 14:25:37 2024 +0300

    Небольшие изменения в реализации операций с множествами

commit 087591c7b6
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Nov 27 11:37:07 2024 +0300

    3.10.1

    Coords - доработки

    Distance, Middle, DrawText с фоном и рамкой. Глобальные переменные настройки

commit d268d4f83b
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Thu Nov 21 22:24:07 2024 +0300

    NSToBytes переделал с исключением

commit 2bacdc8c28
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Nov 20 13:20:33 2024 +0300

    Комментарии к NewSet

commit e917ac8eca
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Nov 20 12:42:15 2024 +0300

    TypeName для set

commit 206289c6a7
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Nov 19 20:23:03 2024 +0300

    Везде заменил _hs на hs в NewSet

    Убрал вызовы методов расширений NewSet в PABCSystem.pas

    Убрал var в operator +

commit d8262078f6
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Nov 19 13:56:47 2024 +0300

    Исправление мелких ошибок NewSet

    Все тесты проходят.

    Проблема, которая остаётся - в режиме ускорения такие программы падают:

    begin
      var s: set of byte;
      Print(s = [1]);
    end.

    Причина - из dll не вызывается конструктор записи без параметров, хотя он определён. В C# вообще у записей не может быть конструктора по умолчанию - наверное потому. Но для NewSet надо бы сделать исключение

commit f8819665ba
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Nov 16 10:56:11 2024 +0300

    NS2

commit 591d9ebe60
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Wed Nov 13 21:34:10 2024 +0100

    fix

commit c6505634f4
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Wed Nov 13 21:12:33 2024 +0100

    fix

commit a6564df23c
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Wed Nov 13 20:52:29 2024 +0100

    fix in new sets

commit 03be5bd931
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Nov 13 22:13:41 2024 +0300

    Переставил operator:= в NewSet

commit 96c68f1666
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Tue Nov 12 21:38:07 2024 +0100

    #3223

commit 82776f3c77
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Nov 9 12:18:19 2024 +0300

    NewSet - много мелких исправлений.

    Все тесты проходят кроме Tests 5 - видимо с pabcrtl.dll

* Update comments in PascalABCLanguageInformation
2025-04-10 13:13:17 +03:00

1250 lines
59 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using PascalABCCompiler.SyntaxTree;
using System.Reflection;
using PascalABCCompiler;
using PascalABCCompiler.TreeRealization;
using PascalABCCompiler.Parsers;
namespace CodeCompletion
{
public struct RetValue
{
public object prim_val;
public string string_val
{
get
{
string s = (string)prim_val;
if (s != null && s.StartsWith("'") && s.EndsWith("'"))
s = s.Substring(1, s.Length - 2);
return s;
}
set
{
prim_val = "'" + value + "'";
}
}
}
public class DomConverter : ICodeCompletionDomConverter
{
public DomSyntaxTreeVisitor visitor;
//TreeConverterSymbolTable tcst;
public CodeCompletionController controller;
public bool is_compiled = false;
// TODO: Требуется адаптировать к многоязычности EVA
public static SymInfo[] standard_units;
private Hashtable cur_used_assemblies;
public CompilationUnit unit;
private void InitModules()
{
try
{
if (CodeCompletionController.comp == null)
return;
string[] files = Directory.GetFiles(Path.Combine(CodeCompletionController.comp.CompilerOptions.SystemDirectory, "Lib"), "*.pas");
standard_units = new SymInfo[files.Length];
int i = 0;
foreach (string s in files)
{
string fname = Path.GetFileNameWithoutExtension(s);
if (fname == "__RedirectIOMode" || fname == "__RunMode" || fname == StringConstants.pascalExtensionsUnitName)
continue;
SymInfo si = new SymInfo(Path.GetFileNameWithoutExtension(s), SymbolKind.Namespace, null);
si.IsUnitNamespace = true;
si.description = GetUnitDescription(s);
standard_units[i++] = si;
}
}
catch (Exception e)
{
//standard_units = new SymInfo[0];
}
}
private string GetUnitDescription(string fileName)
{
var reader = File.OpenText(fileName);
string line = null;
string doc = "";
while (!reader.EndOfStream)
{
line = reader.ReadLine();
if (line.StartsWith("///"))
doc += line.Substring(3) + Environment.NewLine;
else if (line.StartsWith("unit"))
break;
}
reader.Close();
return doc;
}
bool ICodeCompletionDomConverter.IsCompiled
{
get
{
return is_compiled;
}
}
IBaseScope ICodeCompletionDomConverter.EntryScope
{
get
{
return visitor.entry_scope;
}
}
public DomConverter(CodeCompletionController controller)
{
visitor = new DomSyntaxTreeVisitor(this);
this.controller = controller;
if (standard_units == null) InitModules();
}
public void ConvertToDom(compilation_unit cu)
{
if (CodeCompletionController.comp != null)
CodeCompletionController.comp.CompilerOptions.SourceFileName = cu.file_name;
visitor.Convert(cu);
is_compiled = true;
cur_used_assemblies = visitor.cur_used_assemblies;
return;
}
public bool IsAssembliesChanged()
{
return visitor.entry_scope.IsAssembliesChanged();
}
public definition_node[] GetNamesAfterDot(expression expr, string str, int line, int col, PascalABCCompiler.Parsers.KeywordKind keyword, ref definition_node root)
{
unit.SemanticTree.find_by_location(line, col);
return null;
}
/// <summary>
/// Получение имен после точки
/// </summary>
public SymInfo[] GetName(expression expr, string str, int line, int col, PascalABCCompiler.Parsers.KeywordKind keyword, ref SymScope root)
{
if (visitor.cur_scope == null) return null;
if (col + 1 > str.Length)
col -= str.Length;
SymScope si = visitor.FindScopeByLocation(line + 1, col);//stv.cur_scope;
if (si == null)
{
si = visitor.FindScopeByLocation(line, col + 1);
if (si == null)
return null;
}
SetCurrentUsedAssemblies();
string trimed = str.Trim();
if (trimed.Length > 0 && trimed[0] == '(' && trimed[trimed.Length - 1] == ')')
expr = new bracket_expr(expr);
ExpressionVisitor ev = new ExpressionVisitor(expr, si, visitor);
si = ev.GetScopeOfExpression(true, false);
root = si;
if (si is ElementScope) root = (si as ElementScope).sc;
else if (si is ProcScope) root = (si as ProcScope).return_type;
if (si != null)
{
if (!(si is TypeScope) && !(si is NamespaceScope))
{
SymInfo[] syms = si.GetNamesAsInObject(ev);
SymInfo[] ext_syms = null;
if (si is ElementScope)
{
SymScope root_scope = visitor.entry_scope;
//if (root_scope is ImplementationUnitScope || root_scope is BlockScope)
// root_scope = root_scope.topScope;
ext_syms = root_scope.GetSymInfosForExtensionMethods((si as ElementScope).sc as TypeScope);
}
List<SymInfo> lst = new List<SymInfo>();
lst.AddRange(syms);
if (ext_syms != null)
lst.AddRange(ext_syms);
RestoreCurrentUsedAssemblies();
List<SymInfo> lst_to_remove = new List<SymInfo>();
foreach (SymInfo si2 in lst)
if (si2.name.StartsWith("operator"))
lst_to_remove.Add(si2);
foreach (SymInfo si2 in lst_to_remove)
lst.Remove(si2);
return lst.ToArray();
}
else
{
if (si is TypeScope)
{
RestoreCurrentUsedAssemblies();
return (si as TypeScope).GetNames(ev, keyword, false);
}
else
{
if (ev.entry_scope.InUsesRange(line + 1, col + 1))
keyword = PascalABCCompiler.Parsers.KeywordKind.Uses;
RestoreCurrentUsedAssemblies();
return (si as NamespaceScope).GetNames(ev, keyword);
}
}
}
RestoreCurrentUsedAssemblies();
return null;
}
public SymInfo[] GetOverridableMethods(int line, int col)
{
if (visitor.cur_scope == null) return null;
SymScope ss = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (ss == null) return null;
List<SymInfo> meths = new List<SymInfo>();
SetCurrentUsedAssemblies();
if (ss is TypeScope && ((ss as TypeScope).kind == SymbolKind.Class || (ss as TypeScope).kind == SymbolKind.Struct))
{
TypeScope ts = ss as TypeScope;
if (ts.baseScope != null)
{
List<ProcScope> procs = ts.baseScope.GetOverridableMethods();
for (int i = 0; i < procs.Count; i++)
{
SymScope elem = ts.FindNameOnlyInThisType(procs[i].Name);
if (elem == null || !(elem is ProcScope))
{
int pos = 0;
string full_name = CodeCompletionController.CurrentParser.LanguageInformation.ConstructOverridedMethodHeader(procs[i], out pos);
SymInfo si = new SymInfo(full_name.Substring(pos), procs[i].si.kind, full_name);
si.acc_mod = procs[i].si.acc_mod;
meths.Add(si);
}
}
}
}
RestoreCurrentUsedAssemblies();
return meths.ToArray();
}
public ProcScope[] GetNotImplementedMethodHeaders(int line, int col, ref Position pos)
{
if (visitor.cur_scope == null) return null;
SymScope ss = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (ss == null) return null;
List<ProcScope> meths = new List<ProcScope>();
pos.file_name = this.visitor.doc.file_name;
SetCurrentUsedAssemblies();
if (ss is TypeScope && (ss as TypeScope).kind == SymbolKind.Class)
{
TypeScope ts = ss as TypeScope;
pos.line = ts.real_body_loc.begin_line_num;
pos.column = ts.real_body_loc.begin_column_num;
if (ts.baseScope != null)
{
List<ProcScope> procs = ts.baseScope.GetAbstractMethods();
for (int i = 0; i < procs.Count; i++)
{
SymScope elem = ts.FindNameOnlyInThisType(procs[i].Name);
if (elem == null || !(elem is ProcScope))
{
meths.Add(new ProcRealization(procs[i], ts));
}
}
}
if (ts.implemented_interfaces != null)
{
for (int i = 0; i < ts.implemented_interfaces.Count; i++)
{
List<ProcScope> procs = ts.implemented_interfaces[i].GetAbstractMethods();
for (int j = 0; j < procs.Count; j++)
{
SymScope elem = ts.FindNameOnlyInThisType(procs[j].Name);
if (elem == null || !(elem is ProcScope))
{
meths.Add(new ProcRealization(procs[j], ts));
}
else if (elem is ProcScope)
{
ProcScope ps = elem as ProcScope;
bool is_impl = false;
while (ps != null)
if (ps.IsEqual(elem))
{
is_impl = true;
break;
}
else ps = ps.nextProc;
if (!is_impl)
meths.Add(new ProcRealization(procs[j], ts));
}
}
}
}
}
RestoreCurrentUsedAssemblies();
return meths.ToArray();
}
/// <summary>
/// Получение списка нереализованных методов
/// </summary>
public ProcScope[] GetNotImplementedMethods(int line, int col, ref Position pos)
{
try
{
if (visitor.cur_scope == null) return null;
SymScope ss = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (ss == null) return null;
List<ProcScope> meths = new List<ProcScope>();
pos.file_name = this.visitor.doc.file_name;
SetCurrentUsedAssemblies();
if (ss is TypeScope && ((ss as TypeScope).kind == SymbolKind.Class || (ss as TypeScope).kind == SymbolKind.Struct))
{
TypeScope ts = ss as TypeScope;
if (ts.topScope is InterfaceUnitScope)
{
SymScope impl_scope = (ts.topScope as InterfaceUnitScope).impl_scope;
if (impl_scope != null)
{
pos.line = impl_scope.loc.end_line_num;
pos.column = impl_scope.loc.end_column_num + 2;
}
else
{
pos.line = ts.loc.end_line_num;
pos.column = ts.loc.end_column_num + 2;
}
}
else
{
pos.line = ts.loc.end_line_num;
pos.column = ts.loc.end_column_num + 2;
}
foreach (SymScope symsc in ts.members)
{
ProcScope proc = symsc as ProcScope;
if (proc != null && !proc.already_defined && !proc.is_abstract && symsc.loc != null)
{
meths.Add(proc);
}
}
}
else if (ss is ProcScope)
{
TypeScope ts = (ss as ProcScope).topScope as TypeScope;
if (ts != null && (ts.kind == SymbolKind.Class || ts.kind == SymbolKind.Struct))
{
if (ts.topScope is InterfaceUnitScope)
{
SymScope impl_scope = (ts.topScope as InterfaceUnitScope).impl_scope;
if (impl_scope != null)
{
pos.line = impl_scope.loc.end_line_num;
pos.column = impl_scope.loc.end_column_num + 2;
}
else
{
pos.line = ts.loc.end_line_num;
pos.column = ts.loc.end_column_num + 2;
}
}
else
{
pos.line = ts.loc.end_line_num;
pos.column = ts.loc.end_column_num + 2;
}
foreach (SymScope symsc in ts.members)
{
ProcScope proc = symsc as ProcScope;
if (proc != null && !proc.already_defined && !proc.is_abstract && symsc.loc != null)
{
meths.Add(proc);
}
}
}
else if (ts == null && (ss as ProcScope).topScope is InterfaceUnitScope)
{
SymScope impl_scope = ((ss as ProcScope).topScope as InterfaceUnitScope).impl_scope;
if (impl_scope != null)
{
pos.line = impl_scope.loc.end_line_num;
pos.column = impl_scope.loc.end_column_num + 2;
if (!(ss as ProcScope).already_defined && ss.loc != null)
meths.Add(ss as ProcScope);
}
}
}
RestoreCurrentUsedAssemblies();
if (meths.Count > 0) return meths.ToArray();
}
catch
{
}
RestoreCurrentUsedAssemblies();
return null;
}
/// <summary>
/// Получение описания символа
/// </summary>
public IBaseScope GetSymDefinition(expression expr, int line, int col, PascalABCCompiler.Parsers.KeywordKind keyword)
{
if (visitor.cur_scope == null) return null;
SymScope ss = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (ss == null) return null;
bool on_proc = false;
if (keyword == PascalABCCompiler.Parsers.KeywordKind.Function || keyword == PascalABCCompiler.Parsers.KeywordKind.Constructor || keyword == PascalABCCompiler.Parsers.KeywordKind.Destructor)
{
if (ss is ProcRealization)
{
if (expr is ident)
{
if ((expr as ident).name == (ss as ProcRealization).def_proc.si.name) on_proc = true;
}
else on_proc = true;
}
else if (ss is ProcScope)
{
if (expr is ident)
{
if ((expr as ident).name == (ss as ProcScope).si.name) on_proc = true;
}
else on_proc = true;
}
}
//if (!((keyword == KeywordKind.kw_proc || keyword == KeywordKind.kw_constr || keyword == KeywordKind.kw_destr) && ss is ProcScope))
if (!on_proc)
{
SetCurrentUsedAssemblies();
ExpressionVisitor ev = new ExpressionVisitor(expr, ss, visitor);
ss = ev.GetScopeOfExpression();
RestoreCurrentUsedAssemblies();
}
return ss;
}
/// <summary>
/// Нахождение области видимости по координатам курсора
/// </summary>
public SymScope FindScopeByLocation(int line, int col)
{
if (visitor.entry_scope != null)
return visitor.entry_scope.FindScopeByLocation(line, col);
return null;
}
/// <summary>
/// Получение списка пространств имен
/// </summary>
public SymInfo[] GetNamespaces()
{
SymInfo[] elems = visitor.entry_scope.GetNamesInAllTopScopes(true, null, false);
List<SymInfo> result_names = new List<SymInfo>();
result_names.AddRange(standard_units);
if (elems == null) return null;
for (int i = 0; i < elems.Length; i++)
{
if (elems[i].kind == SymbolKind.Namespace && !elems[i].IsUnitNamespace)
result_names.Add(elems[i]);
}
return result_names.ToArray();
}
/// <summary>
/// Получение имен, начинающихся с pattern
/// </summary>
public SymInfo[] GetNameByPattern(string pattern, int line, int col, bool all_names, int nest_level)
{
if (visitor.cur_scope == null) return null;
SymScope si = visitor.FindScopeByLocation(line + 1, col);
if (si == null)
{
si = visitor.FindScopeByLocation(line, col + 1);
if (si == null)
si = visitor.cur_scope;
}
SymInfo[] elems = null;
if (si == null) return null;
if (pattern == null || pattern == "")
elems = si.GetNamesInAllTopScopes(all_names, new ExpressionVisitor(si, visitor), false);
else
elems = si.GetNamesInAllTopScopes(all_names, new ExpressionVisitor(si, visitor), false);
List<SymInfo> result_names = new List<SymInfo>();
if (elems == null) return null;
for (int i = 0; i < elems.Length; i++)
if (pattern == null || pattern == "")
{
if (!elems[i].name.StartsWith("$") && !elems[i].name.StartsWith("<") && !elems[i].name.StartsWith("get_<>") && !elems[i].name.StartsWith("set_<>"))
if (all_names)
{
if (elems[i].kind != SymbolKind.Namespace || nest_level == 0)
result_names.Add(elems[i]);
else
{
string name = elems[i].name;
string tmp = name;
int num_dot = 0;
for (int j = 0; j < nest_level; j++)
{
int pos = tmp.IndexOf('.');
if (pos != -1)
{
num_dot++;
tmp = tmp.Substring(pos + 1, tmp.Length - pos - 1);
}
else break;
}
if (num_dot < nest_level)
result_names.Add(elems[i]);
}
}
else
{
if (elems[i].kind != SymbolKind.Namespace) result_names.Add(elems[i]);
else if (elems[i].name.IndexOf('.') == -1) result_names.Add(elems[i]);
}
}
else
if (elems[i].name.StartsWith(pattern, true, System.Globalization.CultureInfo.CurrentCulture))
result_names.Add(elems[i]);
return result_names.ToArray();
}
/// <summary>
/// Получение типов, начинающихся с pattern
/// </summary>
public SymInfo[] GetTypeByPattern(string pattern, int line, int col, bool all_names, int nest_level)
{
if (visitor.cur_scope == null) return null;
SymScope si = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
SymInfo[] elems = null;
if (si == null)
{
elems = visitor.entry_scope.GetNamesInAllTopScopes(all_names, null, false);
}
else
if (pattern == null || pattern == "") elems = si.GetNamesInAllTopScopes(all_names, new ExpressionVisitor(si, visitor), false);
else elems = si.GetNamesInAllTopScopes(all_names, new ExpressionVisitor(si, visitor), false);
List<SymInfo> result_names = new List<SymInfo>();
if (elems == null) return null;
for (int i = 0; i < elems.Length; i++)
if (pattern != null && pattern != "")
{
if (!elems[i].name.StartsWith("$"))
if (all_names)
{
if (elems[i].kind == SymbolKind.Namespace || elems[i].kind == SymbolKind.Class || elems[i].kind == SymbolKind.Type
|| elems[i].kind == SymbolKind.Struct || elems[i].kind == SymbolKind.Delegate || elems[i].kind == SymbolKind.Enum
|| elems[i].kind == SymbolKind.Interface)
result_names.Add(elems[i]);
}
}
return result_names.ToArray();
}
/// <summary>
/// Выдает все типы (используется после new)
/// </summary>
public SymInfo[] GetTypes(expression expr, int line, int col, out SymInfo out_si)
{
out_si = null;
if (visitor.cur_scope == null) return null;
SymScope si = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
SymInfo[] elems = null;
if (si == null) return null;
elems = si.GetNamesInAllTopScopes(true, new ExpressionVisitor(si, visitor), false);
if (expr != null)
{
ExpressionVisitor ev = new ExpressionVisitor(expr, si, visitor);
si = ev.GetScopeOfExpression();
if (si is TypeScope)
si = new ElementScope(si);
}
List<SymInfo> result_names = new List<SymInfo>();
if (elems == null) return null;
for (int i = 0; i < elems.Length; i++)
{
SymInfo elem_si = elems[i];
if (!elem_si.name.StartsWith("$") && !elem_si.is_static && (elem_si.kind == SymbolKind.Class || elem_si.kind == SymbolKind.Struct || elem_si.kind == SymbolKind.Namespace) && elem_si.kind != SymbolKind.Interface)
{
if (expr != null && si != null && si is ElementScope &&
string.Compare(elem_si.name, (si as ElementScope).sc.si.name, true) == 0)
{
out_si = elem_si;
//out_si = new SymInfo(elems[i].name,elems[i].kind,elems[i].describe);
if ((si as ElementScope).sc is CompiledScope)
{
Type t = ((si as ElementScope).sc as CompiledScope).ctn;
expression name_expr = new ident(out_si.name);
if (out_si.name.IndexOf("<") != -1)
{
template_param_list tpl = new template_param_list();
int num_params = out_si.name.Split(',').Length;
for (var j=0; j<num_params; j++)
tpl.Add(new named_type_reference("T"));
name_expr = new ident_with_templateparams(new ident(out_si.name.Substring(0, out_si.name.IndexOf("<"))), tpl);
}
ExpressionVisitor ev = new ExpressionVisitor(name_expr, visitor.FindScopeByLocation(line + 1, col + 1), visitor);
if (ev.GetScopeOfExpression() == null)
{
out_si.name = t.Namespace + "." + out_si.name;
}
}
string s = CodeCompletionController.CurrentParser.LanguageInformation.GetSimpleDescriptionWithoutNamespace((si as ElementScope).sc as PascalABCCompiler.Parsers.ITypeScope);
if (s != out_si.name)
out_si.addit_name = s;
}
result_names.Add(elem_si);
}
}
if (out_si == null && expr != null && si != null && si is ElementScope)
{
out_si = (si as ElementScope).sc.si;
if (!out_si.name.StartsWith("$") && out_si.kind != SymbolKind.Interface)
{
out_si.name = (si as ElementScope).sc.GetFullName();
if ((si as ElementScope).sc is CompiledScope)
{
Type t = ((si as ElementScope).sc as CompiledScope).ctn;
expression name_expr = new ident(out_si.name);
if (out_si.name.IndexOf("<") != -1)
{
template_param_list tpl = new template_param_list();
int num_params = out_si.name.Split(',').Length;
for (var j = 0; j < num_params; j++)
tpl.Add(new named_type_reference("T"));
name_expr = new ident_with_templateparams(new ident(out_si.name.Substring(0, out_si.name.IndexOf("<"))), tpl);
}
ExpressionVisitor ev = new ExpressionVisitor(name_expr, visitor.FindScopeByLocation(line + 1, col + 1), visitor);
if (ev.GetScopeOfExpression() == null)
{
out_si.name = t.Namespace + "." + out_si.name;
}
}
result_names.Add(out_si);
}
else
{
out_si = null;
}
}
return result_names.ToArray();
}
private string get_references(Type t, out int lines)
{
lines = 0;
StringBuilder assemblies = new StringBuilder();
if (t.Module.ScopeName != "CommonLanguageRuntimeLibrary")
{
assemblies.AppendLine("{$reference " + t.Module.ScopeName + "}");
lines++;
}
AssemblyName[] assm_names = t.Assembly.GetReferencedAssemblies();
for (int i = 0; i < assm_names.Length; i++)
if (assm_names[i].Name != "mscorlib" && assm_names[i].Name != "CommonLanguageRuntimeLibrary")
{
assemblies.AppendLine("{$reference " + assm_names[i].Name + ".dll}");
lines++;
}
return assemblies.ToString();
}
private string prepare_file_name(string name)
{
name = name.Replace('+', '_');
int ind = name.IndexOf('`');
if (ind != -1)
name = name.Substring(0, ind);
return name;
}
/// <summary>
/// Получить определение expr
/// </summary>
public List<Position> GetDefinition(expression expr, int line, int col, PascalABCCompiler.Parsers.KeywordKind keyword, bool only_check)
{
List<Position> poses = new List<Position>();
Position pos = new Position(); pos.line = -1; pos.column = -1;
try
{
if (visitor.cur_scope == null) return poses;
SymScope ss = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (ss == null) return poses;
bool on_proc = false;
SetCurrentUsedAssemblies();
if (keyword == PascalABCCompiler.Parsers.KeywordKind.Function || keyword == PascalABCCompiler.Parsers.KeywordKind.Constructor || keyword == PascalABCCompiler.Parsers.KeywordKind.Destructor)
{
if (ss is ProcRealization)
{
if (expr is ident)
{
if ((expr as ident).name == (ss as ProcRealization).def_proc.si.name)
on_proc = true;
}
else
on_proc = true;
}
else if (ss is ProcScope)
{
if (expr is ident)
{
if ((expr as ident).name == (ss as ProcScope).si.name)
on_proc = true;
}
else
on_proc = true;
}
}
//if (!((keyword == KeywordKind.kw_proc || keyword == KeywordKind.kw_constr || keyword == KeywordKind.kw_destr) && ss is ProcScope))
if (!on_proc)
//if (!((keyword == KeywordKind.kw_proc || keyword == KeywordKind.kw_constr || keyword == KeywordKind.kw_destr) && ss is ProcRealization))
{
ExpressionVisitor ev = new ExpressionVisitor(expr, ss, visitor);
ss = ev.GetScopeOfExpression();
}
else
if (ss is ProcRealization)
ss = (ss as ProcRealization).def_proc;
if (ss != null)
{
if (ss.loc != null)
{
if (!(ss.is_static && ss is ProcScope && (ss as ProcScope).is_constructor))
{
pos.line = ss.loc.begin_line_num;
pos.column = ss.loc.begin_column_num;
pos.file_name = ss.loc.doc.file_name;
poses.Add(pos);
}
}
else if (ss is ProcScope && (ss as ProcScope).is_constructor)
{
ss = (ss as ProcScope).declaringType;
if (ss.loc != null)
{
pos.line = ss.loc.begin_line_num;
pos.column = ss.loc.begin_column_num;
pos.file_name = ss.loc.doc.file_name;
poses.Add(pos);
}
}
else if (ss is CompiledScope)
{
pos.from_metadata = true;
pos.line = 1;
pos.column = 1;
CompiledScope cs = ss as CompiledScope;
pos.metadata_title = prepare_file_name(cs.CompiledType.Name);
pos.full_metadata_title = cs.CompiledType.FullName;
if (cs.CompiledType.IsInterface)
pos.metadata_type = MetadataType.Interface;
else if (cs.CompiledType.BaseType == typeof(Delegate) || cs.CompiledType.BaseType == typeof(MulticastDelegate))
pos.metadata_type = MetadataType.Delegate;
else if (cs.CompiledType.IsEnum)
pos.metadata_type = MetadataType.Enumeration;
else if (cs.CompiledType.IsValueType)
pos.metadata_type = MetadataType.Struct;
else
pos.metadata_type = MetadataType.Class;
if (!only_check)
{
pos.metadata = CodeCompletionController.CurrentParser.LanguageInformation.GetCompiledTypeRepresentation(cs.CompiledType, cs.CompiledType, ref pos.line, ref pos.column);
Type t = cs.CompiledType;
int lines = 0;
int ind = pos.metadata.IndexOf('\n');
pos.metadata = pos.metadata.Insert(ind + 1, get_references(t, out lines));
pos.line += lines;
}
poses.Add(pos);
}
else if (ss is CompiledFieldScope)
{
pos.from_metadata = true;
pos.line = 1;
pos.column = 1;
CompiledFieldScope cfs = ss as CompiledFieldScope;
if (cfs.CompiledField.DeclaringType.IsEnum)
pos.metadata_type = MetadataType.EnumerationMember;
else
pos.metadata_type = MetadataType.Field;
pos.metadata_title = prepare_file_name(cfs.CompiledField.DeclaringType.Name);
if (!only_check)
{
pos.metadata = CodeCompletionController.CurrentParser.LanguageInformation.GetCompiledTypeRepresentation(cfs.CompiledField.DeclaringType, cfs.CompiledField, ref pos.line, ref pos.column);
Type t = cfs.CompiledField.DeclaringType;
int lines = 0;
int ind = pos.metadata.IndexOf('\n');
pos.metadata = pos.metadata.Insert(ind + 1, get_references(t, out lines));
pos.line += lines;
}
pos.full_metadata_title = cfs.CompiledField.DeclaringType.FullName + "." + cfs.CompiledField.Name;
poses.Add(pos);
}
else if (ss is CompiledMethodScope || ss is ProcScope && (ss as ProcScope).original_function is CompiledMethodScope)
{
pos.from_metadata = true;
pos.line = 1;
pos.column = 1;
CompiledMethodScope cms = ss as CompiledMethodScope;
if (cms == null)
cms = (ss as ProcScope).original_function as CompiledMethodScope;
pos.metadata_title = prepare_file_name(cms.CompiledMethod.DeclaringType.Name);
pos.metadata_type = MetadataType.Method;
if (!only_check)
{
pos.metadata = CodeCompletionController.CurrentParser.LanguageInformation.GetCompiledTypeRepresentation(cms.CompiledMethod.DeclaringType, cms.CompiledMethod, ref pos.line, ref pos.column);
Type t = cms.CompiledMethod.DeclaringType;
int lines = 0;
int ind = pos.metadata.IndexOf('\n');
pos.metadata = pos.metadata.Insert(ind + 1, get_references(t, out lines));
pos.line += lines;
}
pos.full_metadata_title = cms.CompiledMethod.DeclaringType.FullName + "." + cms.CompiledMethod.Name;
poses.Add(pos);
}
else if (ss is CompiledPropertyScope)
{
pos.from_metadata = true;
CompiledPropertyScope cps = ss as CompiledPropertyScope;
pos.metadata_title = prepare_file_name(cps.CompiledProperty.DeclaringType.Name);
pos.line = 1;
pos.column = 1;
pos.metadata_type = MetadataType.Property;
if (!only_check)
{
pos.metadata = CodeCompletionController.CurrentParser.LanguageInformation.GetCompiledTypeRepresentation((ss as CompiledPropertyScope).CompiledProperty.DeclaringType, (ss as CompiledPropertyScope).CompiledProperty, ref pos.line, ref pos.column);
Type t = cps.CompiledProperty.DeclaringType;
int lines = 0;
int ind = pos.metadata.IndexOf('\n');
pos.metadata = pos.metadata.Insert(ind + 1, get_references(t, out lines));
pos.line += lines;
}
pos.full_metadata_title = cps.CompiledProperty.DeclaringType.FullName + "." + cps.CompiledProperty.Name;
poses.Add(pos);
}
else if (ss is CompiledConstructorScope)
{
CompiledConstructorScope ccs = ss as CompiledConstructorScope;
pos.from_metadata = true;
pos.line = 1;
pos.column = 1;
pos.metadata_title = prepare_file_name(ccs.CompiledConstructor.DeclaringType.Name);
pos.metadata_type = MetadataType.Constructor;
if (!only_check)
{
pos.metadata = CodeCompletionController.CurrentParser.LanguageInformation.GetCompiledTypeRepresentation(ccs.CompiledConstructor.DeclaringType, ccs.CompiledConstructor, ref pos.line, ref pos.column);
Type t = ccs.CompiledConstructor.DeclaringType;
int lines = 0;
int ind = pos.metadata.IndexOf('\n');
pos.metadata = pos.metadata.Insert(ind + 1, get_references(t, out lines));
pos.line += lines;
}
pos.full_metadata_title = ccs.CompiledConstructor.DeclaringType.FullName + "." + ccs.CompiledConstructor.DeclaringType.Name;
poses.Add(pos);
}
else if (ss is CompiledEventScope)
{
CompiledEventScope ces = ss as CompiledEventScope;
pos.from_metadata = true;
pos.line = 1;
pos.column = 1;
pos.metadata_title = prepare_file_name(ces.CompiledEvent.DeclaringType.Name);
pos.metadata_type = MetadataType.Event;
if (!only_check)
{
pos.metadata = CodeCompletionController.CurrentParser.LanguageInformation.GetCompiledTypeRepresentation(ces.CompiledEvent.DeclaringType, ces.CompiledEvent, ref pos.line, ref pos.column);
Type t = ces.CompiledEvent.DeclaringType;
int lines = 0;
int ind = pos.metadata.IndexOf('\n');
pos.metadata = pos.metadata.Insert(ind + 1, get_references(t, out lines));
pos.line += lines;
}
pos.full_metadata_title = ces.CompiledEvent.DeclaringType.FullName + "." + ces.CompiledEvent.Name;
poses.Add(pos);
}
else if (ss is NamespaceScope)
{
pos.from_metadata = true;
pos.line = 1;
pos.column = 1;
pos.metadata_title = prepare_file_name((ss as NamespaceScope).name);
pos.metadata_type = MetadataType.Event;
pos.full_metadata_title = (ss as NamespaceScope).GetFullName();
poses.Add(pos);
}
}
}
catch (Exception e)
{
}
RestoreCurrentUsedAssemblies();
return poses;
}
/// <summary>
/// Получить реализацию expr
/// </summary>
public List<Position> GetRealization(expression expr, int line, int col, PascalABCCompiler.Parsers.KeywordKind keyword)
{
List<Position> poses = new List<Position>();
Position pos = new Position(); pos.line = -1; pos.column = -1;
try
{
if (visitor.cur_scope == null) return poses;
SymScope ss = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (ss == null) return poses;
//if (!(expr is ident && string.Compare((expr as ident).name,ss.si.name) == 0))
bool on_proc = false;
SetCurrentUsedAssemblies();
if (keyword == PascalABCCompiler.Parsers.KeywordKind.Function || keyword == PascalABCCompiler.Parsers.KeywordKind.Constructor || keyword == PascalABCCompiler.Parsers.KeywordKind.Destructor)
{
if (ss is ProcRealization)
{
if (expr is ident)
{
if ((expr as ident).name == (ss as ProcRealization).def_proc.si.name)
on_proc = true;
}
else
on_proc = true;
}
else if (ss is ProcScope)
{
if (expr is ident)
{
if ((expr as ident).name == (ss as ProcScope).si.name)
on_proc = true;
}
else
on_proc = true;
}
}
//if (!((keyword == KeywordKind.kw_proc || keyword == KeywordKind.kw_constr || keyword == KeywordKind.kw_destr) && ss is ProcScope))
if (!on_proc)
//if (keyword != KeywordKind.kw_proc && keyword != KeywordKind.kw_constr && keyword != KeywordKind.kw_destr)
{
ExpressionVisitor ev = new ExpressionVisitor(expr, ss, visitor);
ss = ev.GetScopeOfExpression();
}
while (ss != null && ss is ProcScope && (ss as ProcScope).procRealization != null && (ss as ProcScope).procRealization.loc != null)
{
ProcRealization pr = (ss as ProcScope).procRealization;
pos.line = pr.loc.begin_line_num;
pos.column = pr.loc.begin_column_num;
pos.file_name = pr.loc.doc.file_name;
poses.Add(pos);
if (on_proc) break;
//ss = (ss as ProcScope).nextProc;
ss = null;
}
}
catch (Exception)
{
}
RestoreCurrentUsedAssemblies();
return poses;
}
/// <summary>
/// Получить описание элемента при наведении мышью
/// </summary>
public string GetDescription(expression expr, string FileName, string expr_without_brackets, int line, int col, PascalABCCompiler.Parsers.KeywordKind keyword, bool header)
{
if (visitor.cur_scope == null) return null;
SymScope ss = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (ss == null) return null;
if (!header && ss.IsInScope(ss.head_loc, line + 1, col + 1))
{
List<PascalABCCompiler.Errors.Error> Errors = new List<PascalABCCompiler.Errors.Error>();
List<PascalABCCompiler.Errors.CompilerWarning> Warnings = new List<PascalABCCompiler.Errors.CompilerWarning>();
expr = Languages.Facade.LanguageProvider.Instance.SelectLanguageByExtension(FileName).Parser.GetExpression("test" + Path.GetExtension(FileName), expr_without_brackets, Errors, Warnings);
if (expr == null || Errors.Count > 0)
return null;
}
bool on_proc = false;
SetCurrentUsedAssemblies();
if (keyword == PascalABCCompiler.Parsers.KeywordKind.Function || keyword == PascalABCCompiler.Parsers.KeywordKind.Constructor || keyword == PascalABCCompiler.Parsers.KeywordKind.Destructor)
{
if (ss is ProcRealization)
{
if (expr is ident)
{
if ((expr as ident).name == (ss as ProcRealization).def_proc.si.name) on_proc = true;
}
else on_proc = true;
}
else if (ss is ProcScope)
{
if (expr is ident)
{
if ((expr as ident).name == (ss as ProcScope).si.name) on_proc = true;
}
else on_proc = true;
}
}
//if (!((keyword == KeywordKind.kw_proc || keyword == KeywordKind.kw_constr || keyword == KeywordKind.kw_destr) && ss is ProcScope))
if (!on_proc)
{
ExpressionVisitor ev = new ExpressionVisitor(expr, ss, visitor);
ev.mouse_hover = true;
ss = ev.GetScopeOfExpression();
if (ss == null && keyword == PascalABCCompiler.Parsers.KeywordKind.SquareBracket &&
expr is ident && !(expr as ident).name.EndsWith("Attribute"))
{
(expr as ident).name = (expr as ident).name + "Attribute";
ss = ev.GetScopeOfExpression();
}
}
if (ss != null && ss.si != null)
{
try
{
if (ss.si.has_doc != true)
if (ss is CompiledScope)
ss.AddDocumentation(AssemblyDocCache.GetDocumentation((ss as CompiledScope).ctn));
else if (ss is CompiledMethodScope)
ss.AddDocumentation(AssemblyDocCache.GetDocumentation((ss as CompiledMethodScope).mi));
else if (ss is CompiledPropertyScope)
ss.AddDocumentation(AssemblyDocCache.GetDocumentation((ss as CompiledPropertyScope).pi));
else if (ss is CompiledFieldScope)
ss.AddDocumentation(AssemblyDocCache.GetDocumentation((ss as CompiledFieldScope).fi));
else if (ss is CompiledEventScope)
ss.AddDocumentation(AssemblyDocCache.GetDocumentation((ss as CompiledEventScope).ei));
else if (ss is CompiledConstructorScope)
ss.AddDocumentation(AssemblyDocCache.GetDocumentation((ss as CompiledConstructorScope).mi));
else if (ss is NamespaceScope)
ss.AddDocumentation(AssemblyDocCache.GetDocumentationForNamespace((ss as NamespaceScope).name));
else if (ss is TypeScope)
ss.AddDocumentation(UnitDocCache.GetDocumentation(ss as TypeScope));
else if (ss is ProcScope)
{
ProcScope ps = ss as ProcScope;
if (ps.is_constructor && ps.is_static)
return null;
if (ps.original_function != null)
ps = ps.original_function;
if (ps is CompiledMethodScope)
ss.AddDocumentation(AssemblyDocCache.GetDocumentation((ps as CompiledMethodScope).mi));
else
ss.AddDocumentation(UnitDocCache.GetDocumentation(ps));
}
else if (ss is InterfaceUnitScope)
ss.AddDocumentation(UnitDocCache.GetDocumentation(ss as InterfaceUnitScope));
else if (ss is ElementScope && string.IsNullOrEmpty(ss.si.description) && (ss as ElementScope).sc is TypeScope)
ss.si.description = (ss as ElementScope).sc.Description;
}
catch (Exception e)
{
#if DEBUG
File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine);
#endif
}
RestoreCurrentUsedAssemblies();
string description = ss.si.description;
if (description != null)
{
description = description.Replace("!#", "");
// Пусть здесь делаем все замены
// Для рекурсивных <<>> нужно писать собственный парсер
//description = System.Text.RegularExpressions.Regex.Replace(description, @"NewSet<\s*(.*)\s*>", "set of $1");
}
return description;
}
RestoreCurrentUsedAssemblies();
return null;
}
/// <summary>
/// Получить подсказку индекса
/// </summary>
public string[] GetIndex(expression expr, int line, int col)
{
if (visitor.cur_scope == null) return null;
SymScope si = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (si == null)
{
si = visitor.FindScopeByLocation(line, col + 1);
if (si == null)
return null;
}
ExpressionVisitor ev = new ExpressionVisitor(expr, si, visitor);
si = ev.GetScopeOfExpression(false, true);
if (si is ProcScope)
{
ProcScope ps = si as ProcScope;
if (ps.is_constructor)
si = new ElementScope(ps.declaringType);
}
string[] description = CodeCompletionController.CurrentParser.LanguageInformation.GetIndexerString(si);
if (description != null)
for (int i = 0; i < description.Length; i++)
{
var arr = si.si.description.Split(new string[1] { "\r\n" }, StringSplitOptions.None);
if (arr.Length > 1 && !string.IsNullOrEmpty(arr[1]))
{
description[i] += si.si.description.Substring(si.si.description.IndexOf("\r\n"));
}
}
return description;
}
/// <summary>
/// Получить подсказку параметров метода
/// </summary>
public string[] GetNameOfMethod(expression expr, string str, int line, int col, int num_param, ref int defIndex, int choose_param_num, out int param_count)
{
param_count = 0;
if (visitor.cur_scope == null) return null;
if (col + 1 > str.Length)
col -= str.Length;
SymScope si = visitor.FindScopeByLocation(line + 1, col + 1);//stv.cur_scope;
if (si == null)
{
si = visitor.FindScopeByLocation(line, col + 1);
if (si == null)
return null;
}
SetCurrentUsedAssemblies();
ExpressionVisitor ev = new ExpressionVisitor(expr, si, visitor);
List<ProcScope> scopes = ev.GetOverloadScopes();
if (scopes.Count == 0)
{
RestoreCurrentUsedAssemblies();
return null;
}
si = scopes[0];
if (si != null && si is ProcScope)
{
List<string> procs = new List<string>();
List<ProcScope> proc_defs = new List<ProcScope>();
ProcScope ps = si as ProcScope;
int i = 0; bool stop = false;
ProcScope tmp = ps;
while (i < scopes.Count)
{
if (i == defIndex)
{
if (tmp.GetParametersCount() != 0)
{
choose_param_num = tmp.GetParametersCount();
param_count = choose_param_num;
}
break;
}
i++;
tmp = scopes[i];
}
i = 0;
while (ps != null)
{
if (!stop && num_param > choose_param_num && ps.GetParametersCount() >= num_param && ps.GetParametersCount() > choose_param_num)
{
defIndex = i;
stop = true;
param_count = ps.GetParametersCount();
}
if (ps is CompiledMethodScope)
ps.AddDocumentation(AssemblyDocCache.GetDocumentation((ps as CompiledMethodScope).mi));
else if (ps is CompiledConstructorScope)
ps.AddDocumentation(AssemblyDocCache.GetDocumentation((ps as CompiledConstructorScope).mi));
else if (ps is ProcScope)
{
if (!ps.si.has_doc)
{
ps.AddDocumentation(UnitDocCache.GetDocumentation(ps as ProcScope));
}
}
if (ps.acc_mod == access_modifer.protected_modifer || ps.acc_mod == access_modifer.private_modifer)
{
if (ps.acc_mod == access_modifer.private_modifer)
{
if (ev.IsInOneModule(ev.entry_scope, ps.topScope))
if (!ps.si.not_include && !equal_params(ps, proc_defs))
{
procs.Add(ps.si.description);
proc_defs.Add(ps);
}
}
else
if (ev.CheckForBaseAccess(ev.entry_scope, ps.topScope))
if (!ps.si.not_include && !equal_params(ps, proc_defs))
{
procs.Add(ps.si.description);
proc_defs.Add(ps);
}
}
else
if (!ps.si.not_include)
if (!equal_params(ps, proc_defs))
{
procs.Add(ps.si.description);
proc_defs.Add(ps);
}
i++;
if (i < scopes.Count)
ps = scopes[i];
else
ps = null;
}
RestoreCurrentUsedAssemblies();
return procs.ToArray();
}
RestoreCurrentUsedAssemblies();
return null;
}
private bool equal_params(ProcScope ps, List<ProcScope> procs)
{
foreach (ProcScope proc in procs)
{
if ((ps.IsOverride || proc.IsOverride) && ps.IsParamsEquals(proc))
return true;
}
return false;
}
private Hashtable tmp_cur_used_assemblies;
//kazhdaja programma mozhet imet svoj spisok podkluchaemyh sborok,
//poetomu nado sohranat i vosstanavlivat tekushij kesh sborok
private void SetCurrentUsedAssemblies()
{
tmp_cur_used_assemblies = PascalABCCompiler.NetHelper.NetHelper.cur_used_assemblies;
PascalABCCompiler.NetHelper.NetHelper.cur_used_assemblies = cur_used_assemblies;
}
private void RestoreCurrentUsedAssemblies()
{
if (tmp_cur_used_assemblies != null)
PascalABCCompiler.NetHelper.NetHelper.cur_used_assemblies = tmp_cur_used_assemblies;
}
~DomConverter()
{
}
}
}