pascalabcnet/VisualPascalABCNET/IB/CodeCompletion/QuickClassBrowserPanel.cs
AlexanderZemlyak 0c29ac92b2
Refactoring of Compiler.cs (#2984)
* Add first comments

* Finish commenting for Compile and CompileUnit

* Write TODO sections

* Add a few clarifications

* splitted some functions from compile

* Written some methods from Compile to functions

* Update variable names

* Refactor - stage 1

Refactor GetUsesSection and IsPossibleNameSpace

* Refactor - stage 2

Rename a few functions and variables

* Correct an inaccuracy

* Added comments, look through CompileUnit

* Rename a few functions and add new comments

* Split CompileUnit to Subfunctions

Add IsUnitCompiled, IsUnitInPCU, InitializeNewUnit, GetSourceCode, GenSyntaxTree, GenUnitDocumentation, CheckDLLDirectiveOnlyForLibraries, MatchErrorsToBadNodes, CheckIfUnitModule, SetUseDLLForSystemUnits,
CompileInterfaceDependencies, CompileCurrentUnitInterface, GetImplementationUsesSection, CompileImplementationDependencies, CompileCurrentUnitImplementation

* Added some TODOs

* Return uses_unit_in original name

Renaming of syntax tree nodes leads to internal compiler errors

* Extract GenerateILCode method

* Add checking if recompilation needed method

Needs to be discussed and revised

* Add functions for catch blocks in Compile

* Extract building semantic tree method

Creating main function to be moved to another class

* Rename UnitsSortedList

* Edit CompileUnitsFromDelayedList method

* Change a few variable names, make CreateRCFile function and add comments

* Make code more "user-friendly"

* Add TODOs 31.11.23

* Create PrebuildSemanticTreeActionsMethod

* Refactor semantic checks section in initialize new unit method

* Refactor Adding standard units to uses method

* Return file_name and compiler_directives original names to avoid internal compilation errors

* Refactor GetReferences Method

* Initial refactoring of IncludeNamespaces function

* Create three more methods and wrap important code in regions

* Add TODO's

* Resolve merge conflicts

* Add returned value to ConstructSyntaxTree method

* Fix UnitsSortedList NotFoundError in PCUWriter

* Workaround commit

* Update PABCSystem after tests' changes

* Rename syntax trees in some methods

* Delete CurrentSyntaxUnit variable

* Revert unnecessary project files changes

* Squashed commit of the following:

commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 22 11:43:29 2023 +0300

    added links to identarranger

commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 22 11:43:03 2023 +0300

    Change extension for verybasic to yavb

commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Tue Nov 21 09:33:57 2023 +0300

    Change Program Example

commit 86971488341ed6bf13c39e13a513d7ac0c51c285
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Tue Nov 21 09:28:59 2023 +0300

    Add IndentArranger to Compile

commit 2ce50bbbf9db22c4243b247b870f6935ce206d26
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Fri Nov 17 10:00:31 2023 +0300

    Add Semicolon After Each Statement

commit 796309d340e8d8ba730ff9418fa376f34fb7fd36
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Wed Nov 15 18:49:11 2023 +0300

    Add Alpha Version of Python-style If-statement

commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227
Merge: ab4ce5b0 0162b637
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 15 16:54:26 2023 +0300

    Merge branch 'IndentArranger' into VeryBasicLanguage

commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 15 16:53:51 2023 +0300

    Fixes from seminar

commit af74012289d0d08517c13499a2a66cb543fc06d2
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Sun Nov 12 18:57:29 2023 +0300

    finally working!

    fully implemented compatibility

commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Sun Nov 12 11:58:16 2023 +0300

    more compatibility with pabc

    Now verybasic statements translate to pascal compiler
    added .bat script for autobuilding verybasic

commit 0162b6376b8fe970704f26213bf9f0f670dfb12e
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Sun Nov 12 10:06:14 2023 +0300

    Update test.txt

commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Sun Nov 12 10:05:36 2023 +0300

    Add Indent and Unindent Keywords to Generated File

commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Fri Nov 10 21:25:52 2023 +0300

    Add Generation of Output File

commit 306f033d0176ab559e3622b8505427dbe2e0e203
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Thu Nov 9 20:42:18 2023 +0300

    Update IndentArranger.sln

commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Thu Nov 9 20:41:22 2023 +0300

    Add IndentArranger

commit 1f4556c4573dae154fcc167b41ff6ab9e8122136
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Mon Nov 6 22:48:36 2023 +0300

    Made my own VeryBasicParser project

    Copied some code from SaushkinParser
    Tried to compile it and implement into Pascal
    Doesn't work due to grammatik issue

* Squashed commit of the following:

commit 4e73d9ac3ffef68312f06a74dc83afffcf3ccbee
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 22 15:08:10 2023 +0300

    Fixed GPPG (i think so at least)

commit e5cfc220828b37fb2f35e565683019716ec3f0ce
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 22 11:44:27 2023 +0300

    Update Compiler.cs

commit 4698e2e75a5f3b4f523a8bc7733a50e8abb4fca1
Merge: 22aaf2b2 f4d7599f
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 22 11:43:54 2023 +0300

    Merge branch 'IndentArrangerTemp' into VeryBasicLanguage

commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 22 11:43:29 2023 +0300

    added links to identarranger

commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 22 11:43:03 2023 +0300

    Change extension for verybasic to yavb

commit 22aaf2b2508278a9ffce525ffed52419bf72c23f
Merge: c326174f 61294c6e
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 22 11:26:36 2023 +0300

    Merge branch 'IndentArrangerTemp' into VeryBasicLanguage

commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Tue Nov 21 09:33:57 2023 +0300

    Change Program Example

commit 86971488341ed6bf13c39e13a513d7ac0c51c285
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Tue Nov 21 09:28:59 2023 +0300

    Add IndentArranger to Compile

commit c326174ff5ecccf9c4f76d58aea4653f047af049
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Sun Nov 19 15:03:19 2023 +0300

    Added UniversalParserHelper and GPPG

    ShiftReduceParser moved to another project
    UniversalParserHelper project added, most of it copied from SaushkinParser

commit 2ce50bbbf9db22c4243b247b870f6935ce206d26
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Fri Nov 17 10:00:31 2023 +0300

    Add Semicolon After Each Statement

commit 796309d340e8d8ba730ff9418fa376f34fb7fd36
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Wed Nov 15 18:49:11 2023 +0300

    Add Alpha Version of Python-style If-statement

commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227
Merge: ab4ce5b0 0162b637
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 15 16:54:26 2023 +0300

    Merge branch 'IndentArranger' into VeryBasicLanguage

commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Wed Nov 15 16:53:51 2023 +0300

    Fixes from seminar

commit af74012289d0d08517c13499a2a66cb543fc06d2
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Sun Nov 12 18:57:29 2023 +0300

    finally working!

    fully implemented compatibility

commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Sun Nov 12 11:58:16 2023 +0300

    more compatibility with pabc

    Now verybasic statements translate to pascal compiler
    added .bat script for autobuilding verybasic

commit 0162b6376b8fe970704f26213bf9f0f670dfb12e
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Sun Nov 12 10:06:14 2023 +0300

    Update test.txt

commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Sun Nov 12 10:05:36 2023 +0300

    Add Indent and Unindent Keywords to Generated File

commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Fri Nov 10 21:25:52 2023 +0300

    Add Generation of Output File

commit 306f033d0176ab559e3622b8505427dbe2e0e203
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Thu Nov 9 20:42:18 2023 +0300

    Update IndentArranger.sln

commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5
Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Date:   Thu Nov 9 20:41:22 2023 +0300

    Add IndentArranger

commit 1f4556c4573dae154fcc167b41ff6ab9e8122136
Author: Владислав Крылов <krylov@sfedu.ru>
Date:   Mon Nov 6 22:48:36 2023 +0300

    Made my own VeryBasicParser project

    Copied some code from SaushkinParser
    Tried to compile it and implement into Pascal
    Doesn't work due to grammatik issue

* Changed GPPG project NET Framework version, added .dll to gitignore

* Adding UniversalParserHelper to project, trying to include VeryBasic

* Managed dependencies and got VeryBasicLanguage to work

* Change extension of a test program

* Rebuild changes

What should be added to .gitignore?

* Fix bug related to err0524_res_unit.pas

* Rebuild Parser

* Change Indent and Unindent tokens

* Add Symbol Table to ParserABC.y

* Change Indent Space Number to 2

* Add While Loop

* Add Some Operations to Parser

* Make Initialization Node at the Beginning of a program

* Create Grammar.txt

* Test program added

* Add ELIF and SyntaxHighlight

* Fix TableSymbol

* Add Division

* Add Method Call

* Add For Loop

* Rename SPython Parser Folder

* Add documented comments for CompileUnit method

* Added Errors to SPython

Added Errors.cs
Removed link to PABCSaushkinParser
Minor fixes

* Create default constructor for SourceContext

* Move null check of currentUnit to upper level in CompileUnit

* Move CreateMainFunction method from Compiler to TreeConverter class

* Add gppg and parserhelper to visualpascalabcnet dependencies

* Updated installer files to include GPPG and UniversalParserHelper

* Rename GPPG to ShiftReduceParser

* Fix ShiftReduceParser project dependencies

* Fix ShiftReduceParserDependencies second iteration

* Workaround commit

* Update PABCSystem after tests' changes

* Refactor ConvertDirectives method

* Get rid of legacy standard modules code

* Return varBeginOffset and beginOffset calculation to Compiler class

Размещение метода в SyntaxTreeToSemanticTreeConverter не целесообразно. В комментарии видимо имелось в виду что-то другое.

* Workaround commit

* Update PABCSystem after tests' changes

* Revert SPython changes

Оставляем только изменения связанные с рефакторингом.

* Update .gitignore

Co-authored-by: Sun Serega <sunserega2@gmail.com>

* Resolve a few Sun Serega treds

* Delete comments in ParsersController.cs

* Replace specific path with path variable in Studio.bat

* Add comment in Studio.bat file and return FileName in CompilerError.cs

* Fix TreeSubsidiary.cs encoding and sectCore.nsh indents

* Return old version of TestRunner.exe

* Rename some variables and polish a few methods

* Uncomment accidentally commented code

* Replace spaces with tabs

* Changed dll name from GPPG

* Revert "Changed dll name from GPPG"

This reverts commit c485cc8cb787809b7e9dfa8a361e75f17ed39893.

* Update .gitignore

* Delete Libraries/ShiftReduceParser.dll

* Delete bin\ShiftReduceParser.dll

* Replace tabs with spaces

* Update encoding in Studio.bat

* Fix bug with PABCrtl excluded files

* Refactor StandardModule class

* Add null checks to make debuging easier

* Delete unnecessary null checks in SymTable.cs

---------

Co-authored-by: Владислав Крылов <krylov@sfedu.ru>
Co-authored-by: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com>
Co-authored-by: Sun Serega <sunserega2@gmail.com>
2023-12-18 22:33:27 +03:00

897 lines
35 KiB
C#

// 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.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using CodeCompletion;
using System.Threading;
using PascalABCCompiler.Parsers;
namespace VisualPascalABC
{
public class QuickClassBrowserPanel : System.Windows.Forms.UserControl
{
private System.Windows.Forms.ComboBox classComboBox;
private System.Windows.Forms.ComboBox membersComboBox;
IBaseScope currentCompilationUnit;
CodeFileDocumentTextEditorControl textAreaControl;
bool autoselect = true;
class ComboBoxItem : System.IComparable
{
IBaseScope item;
string text;
int iconIndex;
bool isInCurrentPart;
Position pos;
bool is_global;
public int IconIndex {
get {
return iconIndex;
}
}
public IBaseScope Item {
get {
return item;
}
}
public bool IsInCurrentPart {
get {
return isInCurrentPart;
}
}
public Position ItemRegion {
get {
return pos;
}
}
public int Line {
get {
return pos.line-1;
}
}
public int Column {
get {
return pos.column-1;
}
}
public int EndLine {
get {
return pos.end_line-1;
}
}
public ComboBoxItem(IBaseScope item, string text, int iconIndex, bool isInCurrentPart, bool is_global)
{
this.item = item;
if (item != null)
pos = item.GetPosition();
this.text = text;
this.iconIndex = iconIndex;
this.isInCurrentPart = true;
this.is_global = is_global;
}
public bool IsInside(int lineNumber, int columnNumber)
{
if (item == null || is_global) return true;
if (pos.line < lineNumber+1 && pos.end_line > lineNumber+1) return true;
if (pos.line > lineNumber+1 || pos.end_line < lineNumber+1) return false;
if (pos.line == lineNumber+1 && pos.end_line == lineNumber+1)
{
if (pos.column <= columnNumber+1 && pos.end_column >= columnNumber+1) return true;
else return false;
}
else if (pos.end_line != lineNumber+1 && pos.column <= columnNumber+1) return true;
else if (pos.line != lineNumber+1 && pos.end_column >= columnNumber+1) return true;
return false;
}
public int CompareItemTo(object obj)
{
ComboBoxItem boxItem = (ComboBoxItem)obj;
if (boxItem.Item is IComparable) {
return ((IComparable)boxItem.Item).CompareTo(item);
}
if (boxItem.text != text || boxItem.Line != Line || boxItem.EndLine != EndLine || boxItem.iconIndex != iconIndex) {
return 1;
}
return 0;
}
string cachedString;
public override string ToString()
{
// ambience lookups can be expensive when the return type is
// resolved on the fly.
// Therefore, we need to cache the generated string because it is used
// very often for the sorting.
if (cachedString == null)
cachedString = ToStringInternal();
return cachedString;
}
string ToStringInternal()
{
if (text == null) return "";
return text;
}
#region System.IComparable interface implementation
public int CompareTo(object obj)
{
return ToString().CompareTo(obj.ToString());
}
#endregion
}
public QuickClassBrowserPanel(CodeFileDocumentTextEditorControl textAreaControl)
{
InitializeComponent();
this.membersComboBox.DropDownHeight = Convert.ToInt32(this.membersComboBox.DropDownHeight * ScreenScale.Calc());
this.classComboBox.DropDownHeight = Convert.ToInt32(this.classComboBox.DropDownHeight * ScreenScale.Calc());
this.membersComboBox.MaxDropDownItems = 20;
base.Dock = DockStyle.Top;
this.textAreaControl = textAreaControl;
this.textAreaControl.ActiveTextAreaControl.Caret.PositionChanged += new EventHandler(CaretPositionChanged);
if (VisualPABCSingleton.MainForm != null && !VisualPABCSingleton.MainForm.UserOptions.ShowQuickClassBrowserPanel)
{
this.Visible = false;
}
if (VisualPABCSingleton.MainForm != null)
{
th = new Thread(new ThreadStart(ChangeInternal));
th.Priority = ThreadPriority.Lowest;
th.IsBackground = true;
th.Start();
}
}
new public bool Visible
{
get
{
return base.Visible;
}
set
{
if (value)
ShowPanel();
else
HidePanel();
}
}
public void ShowPanel()
{
base.Visible = true;
}
public void HidePanel()
{
base.Visible = false;
}
private void PaintInternal(object sender, PaintEventArgs e)
{
//base.OnPaint(e);
//e.Graphics.DrawLine(new Pen(SystemColors.ControlLight,0.1F),e.ClipRectangle.Left,e.ClipRectangle.Bottom-3,e.ClipRectangle.Right,e.ClipRectangle.Bottom-3);
//e.Graphics.DrawLine(new Pen(SystemColors.ControlDark,0.1F),e.ClipRectangle.Left,e.ClipRectangle.Bottom-1,e.ClipRectangle.Right,e.ClipRectangle.Bottom-1);
}
protected override void Dispose(bool disposing)
{
if (disposing) {
this.textAreaControl.ActiveTextAreaControl.Caret.PositionChanged -= new EventHandler(CaretPositionChanged);
this.membersComboBox.Dispose();
this.classComboBox.Dispose();
this.currentCompilationUnit = null;
th.Abort();
}
base.Dispose(disposing);
}
void ChangeInternal()
{
bool first_comp;
ICodeCompletionDomConverter dconv =null;
bool tmp = true;
while (true)
{
first_comp = false;
if (this.Visible)
try
{
if (currentCompilationUnit == null && textAreaControl.FileName != null)
{
dconv = WorkbenchServiceFactory.CodeCompletionParserController.GetConverter(textAreaControl.FileName);
if (dconv != null && dconv.IsCompiled)
{
currentCompilationUnit = dconv.EntryScope;
first_comp = true;
}
if (clicked || tmp)
{
FillClassComboBox(true);
//clicked = false;
tmp = false;
}
}
if (currentCompilationUnit != null && (clicked || first_comp))
{
dconv = WorkbenchServiceFactory.CodeCompletionParserController.GetConverter(textAreaControl.FileName);
if (dconv != null && dconv.IsCompiled)
{
currentCompilationUnit = dconv.EntryScope;
FillClassComboBox(true);
}
}
//lock(clicked)
{
clicked = false;
}
}
catch (Exception ex)
{
//MessageService.ShowError(ex);
}
Thread.Sleep(300);
}
}
Thread th;
bool clicked = false;
IAsyncResult ar;
void CaretPositionChanged(object sender, EventArgs e)
{
// ignore simple movements
if (e != EventArgs.Empty) {
return;
}
clicked = true;
}
bool membersComboBoxSelectedMember = false;
void UpdateMembersComboBox()
{
membersComboBox.Invoke(new Invoke_del(Member_Invoke_Refresh));
autoselect = false;
try
{
if (currentCompilationUnit != null)
{
for (int i = 0; i < membersComboBox.Items.Count; ++i)
{
if (((ComboBoxItem)membersComboBox.Items[i]).IsInside(textAreaControl.ActiveTextAreaControl.Caret.Line, textAreaControl.ActiveTextAreaControl.Caret.Column))
{
if ((int)membersComboBox.Invoke(new Invoke_del_with_ret(GetSelectedMemberInternal)) != i)
{
membersComboBox.Invoke(new Invoke_param_del(SetSelectedMemberItemInternal), i);
}
if (!membersComboBoxSelectedMember)
{
membersComboBox.Invoke(new Invoke_del(Member_Invoke_Refresh));
}
membersComboBoxSelectedMember = true;
return;
}
}
}
membersComboBox.Invoke(new Invoke_param_del(SetSelectedMemberItemInternal), -1);
if (membersComboBoxSelectedMember)
{
membersComboBox.Invoke(new Invoke_del(Member_Invoke_Refresh));
membersComboBoxSelectedMember = false;
}
}
catch (Exception e)
{
}
finally {
autoselect = true;
}
}
bool classComboBoxSelectedMember = false;
void UpdateClassComboBox(bool need_fill_members)
{
// Still needed ?
/*if (currentCompilationUnit == null) {
currentCompilationUnit = (ICompilationUnit)ParserService.GetParseInformation(Path.GetFullPath(textAreaControl.file_name)).MostRecentCompilationUnit;
}*/
autoselect = false;
Dictionary<ComboBoxItem, int> ns_list = new Dictionary<ComboBoxItem, int>();
try
{
for (int i = 0; i < classComboBox.Items.Count; i++)
{
if (((ComboBoxItem)classComboBox.Items[i]).IsInside(textAreaControl.ActiveTextAreaControl.Caret.Line, textAreaControl.ActiveTextAreaControl.Caret.Column))
{
bool innerClassContainsCaret = false;
if (((ComboBoxItem)classComboBox.Items[i]).Item == null || ((ComboBoxItem)classComboBox.Items[i]).Item.SymbolInfo.kind == SymbolKind.Namespace)
{
ns_list[(ComboBoxItem)classComboBox.Items[i]] = i;
continue;
}
if (!innerClassContainsCaret)
{
if ((int)classComboBox.Invoke(new Invoke_del_with_ret(GetSelectedClassInternal)) != i)
{
//classComboBox.SelectedIndex = i;
classComboBox.Invoke(new Invoke_param_del(SetSelectedClassItemInternal), i);
if (need_fill_members)
FillMembersComboBox();
}
if (!classComboBoxSelectedMember)
{
classComboBox.Invoke(new Invoke_del(Invoke_Refresh));
}
classComboBoxSelectedMember = true;
return;
}
}
}
foreach (ComboBoxItem cbi in ns_list.Keys)
{
if (cbi.Item is ImplementationUnitScope && cbi.IsInside(textAreaControl.ActiveTextAreaControl.Caret.Line, textAreaControl.ActiveTextAreaControl.Caret.Column))
{
//classComboBox.SelectedIndex = (int)ns_list[cbi];
classComboBox.Invoke(new Invoke_param_del(SetSelectedClassItemInternal), ns_list[cbi]);
if (need_fill_members)
FillMembersComboBox();
classComboBox.Invoke(new Invoke_del(Invoke_Refresh));
classComboBoxSelectedMember = true;
return;
}
else
{
//classComboBox.SelectedIndex = (int)ns_list[cbi];
classComboBox.Invoke(new Invoke_param_del(SetSelectedClassItemInternal), ns_list[cbi]);
classComboBoxSelectedMember = true;
}
}
if (need_fill_members)
FillMembersComboBox();
classComboBox.Invoke(new Invoke_del(Invoke_Refresh));
return;
}
finally
{
autoselect = true;
}
// classComboBox.SelectedIndex = -1;
}
IBaseScope GetCurrentSelectedClass()
{
try
{
if ((int)classComboBox.Invoke(new Invoke_del_with_ret(GetSelectedClassInternal)) >= 0)
{
return (IBaseScope)((ComboBoxItem)classComboBox.Items[(int)classComboBox.Invoke(new Invoke_del_with_ret(GetSelectedClassInternal))]).Item;
}
}
catch (Exception ex)
{
}
return null;
}
IBaseScope GetCurrentSelectedMember()
{
if ((int)membersComboBox.Invoke(new Invoke_del_with_ret(GetSelectedClassInternal)) >= 0)
{
return (IBaseScope)((ComboBoxItem)membersComboBox.Items[(int)membersComboBox.Invoke(new Invoke_del_with_ret(GetSelectedClassInternal))]).Item;
}
return null;
}
bool NeedtoUpdate(ArrayList items, ComboBox comboBox)
{
if (items.Count != comboBox.Items.Count)
{
return true;
}
for (int i = 0; i < items.Count; ++i)
{
ComboBoxItem oldItem = (ComboBoxItem)comboBox.Items[i];
ComboBoxItem newItem = (ComboBoxItem)items[i];
if (oldItem.GetType() != newItem.GetType())
{
return true;
}
if (newItem.CompareItemTo(oldItem) != 0)
{
return true;
}
}
return false;
}
//IClass lastClassInMembersComboBox;
void GetGlobalUnitMembers(ArrayList items)
{
foreach (IBaseScope ss in currentCompilationUnit.Members)
{
switch (ss.SymbolInfo.kind)
{
case SymbolKind.Method:
case SymbolKind.Constant:
case SymbolKind.Variable:
case SymbolKind.Event:
case SymbolKind.Field:
case SymbolKind.Parameter:
case SymbolKind.Property:
items.Add(new ComboBoxItem(ss, ss.GetDescriptionWithoutDoc(), CodeCompletionProvider.ImagesProvider.GetPictureNum(ss.SymbolInfo), true, false));
break;
}
}
int ind = items.Count;
items.Sort(0, items.Count, new Comparer(System.Globalization.CultureInfo.InvariantCulture));
if ((currentCompilationUnit as IInterfaceUnitScope).ImplementationUnitScope != null)
{
IImplementationUnitScope us = (currentCompilationUnit as IInterfaceUnitScope).ImplementationUnitScope;
//items.Add(new ComboBoxItem(us,"implementation",CodeCompletionProvider.ImagesProvider.GetPictureNum(us.si),true));
foreach (IBaseScope ss in us.Members)
{
switch (ss.SymbolInfo.kind)
{
case SymbolKind.Method:
case SymbolKind.Constant:
case SymbolKind.Variable:
case SymbolKind.Event:
case SymbolKind.Field:
case SymbolKind.Parameter:
case SymbolKind.Property:
items.Add(new ComboBoxItem(ss, ss.GetDescriptionWithoutDoc(), CodeCompletionProvider.ImagesProvider.GetPictureNum(ss.SymbolInfo), true, false));
break;
}
}
items.Sort(ind, items.Count - ind, new Comparer(System.Globalization.CultureInfo.InvariantCulture));
}
}
void GetClassMembers(IBaseScope scope, ArrayList items)
{
if (scope != null && scope.Members != null)
{
ArrayList meths = new ArrayList();
ArrayList fields = new ArrayList();
ArrayList events = new ArrayList();
ArrayList vars = new ArrayList();
ArrayList props = new ArrayList();
ArrayList consts = new ArrayList();
foreach (IBaseScope el in scope.Members)
if (el.GetPosition().file_name != null && !el.SymbolInfo.not_include)
{
ComboBoxItem cbi = new ComboBoxItem(el, el.GetDescriptionWithoutDoc(), CodeCompletionProvider.ImagesProvider.GetPictureNum(el.SymbolInfo), true, false);
switch (el.SymbolInfo.kind)
{
case SymbolKind.Method: meths.Add(cbi); break;
case SymbolKind.Field: fields.Add(cbi); break;
case SymbolKind.Property: props.Add(cbi); break;
case SymbolKind.Variable: vars.Add(cbi); break;
case SymbolKind.Event: events.Add(cbi); break;
case SymbolKind.Constant: consts.Add(cbi); break;
}
//items.Add(new ComboBoxItem(el,el.GetDescriptionWithoutDoc(),CodeCompletionProvider.ImagesProvider.GetPictureNum(el.si),true));
}
meths.Sort(new Comparer(System.Globalization.CultureInfo.InvariantCulture));
items.AddRange(meths);
props.Sort(new Comparer(System.Globalization.CultureInfo.InvariantCulture));
items.AddRange(props);
fields.Sort(new Comparer(System.Globalization.CultureInfo.InvariantCulture));
items.AddRange(fields);
vars.Sort(new Comparer(System.Globalization.CultureInfo.InvariantCulture));
items.AddRange(vars);
consts.Sort(new Comparer(System.Globalization.CultureInfo.InvariantCulture));
items.AddRange(consts);
events.Sort(new Comparer(System.Globalization.CultureInfo.InvariantCulture));
items.AddRange(events);
}
}
void FillMembersComboBox()
{
ArrayList items = new ArrayList();
IBaseScope scope = GetCurrentSelectedClass();
if (scope == null)
{
GetGlobalUnitMembers(items);
//items.Sort(0,items.Count,new Comparer(System.Globalization.CultureInfo.InvariantCulture));
}
else
{
GetClassMembers(scope, items);
//items.Sort(0,items.Count,new Comparer(System.Globalization.CultureInfo.InvariantCulture));
}
if (NeedtoUpdate(items, membersComboBox))
{
membersComboBox.Invoke(new Invoke_del(Member_Invoke_Update));
membersComboBox.Invoke(new Invoke_del(Member_Invoke_Clear));
//membersComboBox.Items.AddRange(items.ToArray());
membersComboBox.Invoke(new Invoke_param_del(AddItemsToMembersComboboxInternal), items);
UpdateMembersComboBox();
membersComboBox.Invoke(new Invoke_del(Member_Invoke_EndUpdate));
}
else
{
membersComboBox.Invoke(new Invoke_del(Member_Invoke_Update));
UpdateMembersComboBox();
membersComboBox.Invoke(new Invoke_del(Member_Invoke_EndUpdate));
}
}
void AddClasses(ArrayList items)
{
IImplementationUnitScope impl = null;
int ind = 0;
if (currentCompilationUnit == null)
{
//items.Add(new ComboBoxItem(currentCompilationUnit,PascalABCCompiler.StringResources.Get("CODE_COMPLETION_GLOBAL"),CodeCompletionProvider.ImagesProvider.IconNumberUnitNamespace,true,true));
return;
}
if ((currentCompilationUnit as InterfaceUnitScope).impl_scope != null)
{
items.Add(new ComboBoxItem(currentCompilationUnit, PascalABCCompiler.StringResources.Get("CODE_COMPLETION_INTERFACE"), CodeCompletionProvider.ImagesProvider.GetPictureNum(currentCompilationUnit.SymbolInfo), true, false));
impl = (currentCompilationUnit as IInterfaceUnitScope).ImplementationUnitScope;
items.Add(new ComboBoxItem(impl, PascalABCCompiler.StringResources.Get("CODE_COMPLETION_IMPLEMENTATION"), CodeCompletionProvider.ImagesProvider.GetPictureNum(impl.SymbolInfo), true, false));
ind = 2;
}
else
{
items.Add(new ComboBoxItem(currentCompilationUnit, PascalABCCompiler.StringResources.Get("CODE_COMPLETION_GLOBAL"), CodeCompletionProvider.ImagesProvider.IconNumberUnitNamespace, true, true));
ind = 1;
}
foreach (IBaseScope ss in currentCompilationUnit.Members)
{
switch (ss.SymbolInfo.kind)
{
case SymbolKind.Class:
case SymbolKind.Struct:
case SymbolKind.Type:
case SymbolKind.Enum:
case SymbolKind.Interface:
case SymbolKind.Delegate:
if (ss.GetPosition().file_name != null && !ss.SymbolInfo.name.Contains("$") && !ss.SymbolInfo.name.StartsWith("<"))
items.Add(new ComboBoxItem(ss, ss.SymbolInfo.name, CodeCompletionProvider.ImagesProvider.GetPictureNum(ss.SymbolInfo), true, false));
break;
}
}
if (impl != null)
foreach (IBaseScope ss in impl.Members)
{
switch (ss.SymbolInfo.kind)
{
case SymbolKind.Class:
case SymbolKind.Struct:
case SymbolKind.Type:
case SymbolKind.Enum:
case SymbolKind.Interface:
case SymbolKind.Delegate:
if (ss.GetPosition().file_name != null && !ss.SymbolInfo.name.Contains("$") && !ss.SymbolInfo.name.StartsWith("<"))
items.Add(new ComboBoxItem(ss, ss.SymbolInfo.name, CodeCompletionProvider.ImagesProvider.GetPictureNum(ss.SymbolInfo), true, false));
break;
}
}
items.Sort(ind, items.Count - ind, new Comparer(System.Globalization.CultureInfo.InvariantCulture));
}
delegate void Invoke_del();
delegate void Invoke_param_del(object obj);
delegate object Invoke_del_with_ret();
void Invoke_Update()
{
classComboBox.BeginUpdate();
}
void Invoke_EndUpdate()
{
classComboBox.EndUpdate();
}
void Invoke_Clear()
{
classComboBox.Items.Clear();
}
void Invoke_Refresh()
{
classComboBox.Refresh();
}
void Member_Invoke_Update()
{
membersComboBox.BeginUpdate();
}
void Member_Invoke_EndUpdate()
{
membersComboBox.EndUpdate();
}
void Member_Invoke_Clear()
{
membersComboBox.Items.Clear();
}
void Member_Invoke_Refresh()
{
membersComboBox.Refresh();
}
void AddItemsToClassComboboxInternal(object items)
{
lock(classComboBox)
{
classComboBox.Items.AddRange(((ArrayList)items).ToArray());
}
}
void AddItemsToMembersComboboxInternal(object items)
{
lock (membersComboBox)
{
membersComboBox.Items.AddRange(((ArrayList)items).ToArray());
}
}
void SetSelectedClassItemInternal(object item)
{
classComboBox.SelectedIndex = (int)item;
}
void SetSelectedMemberItemInternal(object item)
{
membersComboBox.SelectedIndex = (int)item;
}
object GetSelectedClassInternal()
{
return classComboBox.SelectedIndex;
}
object GetSelectedMemberInternal()
{
return membersComboBox.SelectedIndex;
}
void FillClassComboBox(bool isUpdateRequired)
{
try //временно, исправть ошибку
{
if (isUpdateRequired)
{
classComboBox.Invoke(new Invoke_del(Invoke_Update));
}
ArrayList items = new ArrayList();
bool only_global = false;
AddClasses(items);
if (items.Count == 0)
{
items.Add(new ComboBoxItem(currentCompilationUnit, PascalABCCompiler.StringResources.Get("CODE_COMPLETION_GLOBAL"), CodeCompletionProvider.ImagesProvider.IconNumberUnitNamespace, true, true));
only_global = true;
}
classComboBox.Invoke(new Invoke_del(Invoke_Clear));
//здесь ошибка доступа из другого потока [DSRE0001]
//classComboBox.Items.AddRange(items.ToArray());
classComboBox.Invoke(new Invoke_param_del(AddItemsToClassComboboxInternal), items);
if (items.Count == 1)
{
try
{
autoselect = false;
//classComboBox.SelectedIndex = 0;
//FillMembersComboBox();
}
finally
{
autoselect = true;
}
}
UpdateClassComboBox(!only_global);
if (isUpdateRequired)
{
classComboBox.Invoke(new Invoke_del(Invoke_EndUpdate));
}
}
catch (Exception )
{
}
}
// THIS METHOD IS MAINTAINED BY THE FORM DESIGNER
// DO NOT EDIT IT MANUALLY! YOUR CHANGES ARE LIKELY TO BE LOST
void InitializeComponent() {
this.membersComboBox = new System.Windows.Forms.ComboBox();
this.classComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// membersComboBox
//
this.membersComboBox.Dock = System.Windows.Forms.DockStyle.Right;
this.membersComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
this.membersComboBox.DropDownHeight = 250;
this.membersComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.membersComboBox.Font = new System.Drawing.Font("Arial", 9F);
this.membersComboBox.IntegralHeight = false;
this.membersComboBox.Location = new System.Drawing.Point(198, 0);
this.membersComboBox.Margin = new System.Windows.Forms.Padding(3, 3, 3, 1);
this.membersComboBox.Name = "membersComboBox";
this.membersComboBox.Size = new System.Drawing.Size(212, 22);
this.membersComboBox.TabIndex = 1;
this.membersComboBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.ComboBoxDrawItem);
this.membersComboBox.DropDown += new System.EventHandler(this.ComboBoxDropDown);
this.membersComboBox.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.MeasureComboBoxItem);
this.membersComboBox.SelectedIndexChanged += new System.EventHandler(this.ComboBoxSelectedIndexChanged);
//
// classComboBox
//
this.classComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
this.classComboBox.DropDownHeight = 150;
this.classComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.classComboBox.Font = new System.Drawing.Font("Arial", 9F);
this.classComboBox.IntegralHeight = false;
this.classComboBox.Location = new System.Drawing.Point(1, 0);
this.classComboBox.Margin = new System.Windows.Forms.Padding(3, 3, 3, 1);
this.classComboBox.Name = "classComboBox";
this.classComboBox.Size = new System.Drawing.Size(189, 22);
this.classComboBox.TabIndex = 0;
this.classComboBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.ComboBoxDrawItem);
this.classComboBox.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.MeasureComboBoxItem);
this.classComboBox.SelectedIndexChanged += new System.EventHandler(this.ComboBoxSelectedIndexChanged);
//
// QuickClassBrowserPanel
//
this.AutoSize = true;
this.Controls.Add(this.membersComboBox);
this.Controls.Add(this.classComboBox);
this.Name = "QuickClassBrowserPanel";
this.Size = new System.Drawing.Size(410, 23);
this.Resize += new System.EventHandler(this.QuickClassBrowserPanelResize);
this.ResumeLayout(false);
}
void ComboBoxDropDown(object sender, System.EventArgs e)
{
}
void ComboBoxSelectedIndexChanged(object sender, System.EventArgs e)
{
try
{
ComboBox comboBox = (ComboBox)sender;
if (autoselect)
{
ComboBoxItem item = null;
if (comboBox == classComboBox)
item = (ComboBoxItem)comboBox.Items[(int)comboBox.Invoke(new Invoke_del_with_ret(GetSelectedClassInternal))];
else
item = (ComboBoxItem)comboBox.Items[(int)comboBox.Invoke(new Invoke_del_with_ret(GetSelectedMemberInternal))];
if (item.IsInCurrentPart)
{
//textAreaControl.ActiveTextAreaControl.Caret.Position = new ICSharpCode.TextEditor.TextLocation(item.Column, item.Line);
//textAreaControl.ActiveTextAreaControl.TextArea.Focus();
//VisualPABCSingleton.MainForm.ExecuteSourceLocationAction(new PascalABCCompiler.SourceLocation(textAreaControl.file_name,item.Line+1,item.Column,
// item.EndLine+1,item.Column),VisualPascalABCPlugins.SourceLocationAction.NavigationGoto);
VisualPABCSingleton.MainForm.VisualEnvironmentCompiler.ExecuteSourceLocationAction(
new PascalABCCompiler.SourceLocation(textAreaControl.FileName, item.Line + 1, item.Column + 1, item.Line + 1, item.Column + 1), VisualPascalABCPlugins.SourceLocationAction.GotoBeg);
}
else
{
}
if (comboBox == classComboBox)
{
FillMembersComboBox();
UpdateMembersComboBox();
}
}
}
catch (Exception)
{
}
}
// font - has to be static - don't create on each draw
static Font font = font = new Font("Tahoma", 8.5f);
static StringFormat drawStringFormat = new StringFormat(StringFormatFlags.NoWrap);
void ComboBoxDrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
lock (comboBox)
{
e.DrawBackground();
if (e.Index >= 0)
{
ComboBoxItem item = (ComboBoxItem)comboBox.Items[e.Index];
var dx = Convert.ToInt32(Math.Round(2 * ScreenScale.Calc()));
e.Graphics.DrawImage(CodeCompletionProvider.ImagesProvider.ImageList.Images[item.IconIndex],
e.Bounds.X + dx, e.Bounds.Y, // + (e.Bounds.Height - CodeCompletionProvider.ImagesProvider.ImageList.ImageSize.Height) / 2
e.Bounds.Height, e.Bounds.Height
);
Rectangle drawingRect = new Rectangle(e.Bounds.X + dx + e.Bounds.Height/*CodeCompletionProvider.ImagesProvider.ImageList.ImageSize.Width*/,
e.Bounds.Y,
e.Bounds.Width - dx - e.Bounds.Height/*CodeCompletionProvider.ImagesProvider.ImageList.ImageSize.Width*/,
e.Bounds.Height);
Brush drawItemBrush = SystemBrushes.WindowText;
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
drawItemBrush = SystemBrushes.HighlightText;
}
if (!item.IsInCurrentPart)
{
drawItemBrush = SystemBrushes.ControlDark;
}
else if (e.State == DrawItemState.ComboBoxEdit && !item.IsInside(textAreaControl.ActiveTextAreaControl.Caret.Line, textAreaControl.ActiveTextAreaControl.Caret.Column))
{
drawItemBrush = SystemBrushes.ControlDark;
}
e.Graphics.DrawString(item.ToString(),
font,
drawItemBrush,
drawingRect,
drawStringFormat);
}
//e.DrawFocusRectangle();
}
}
void QuickClassBrowserPanelResize(object sender, System.EventArgs e)
{
Size comboBoxSize = new Size(Width / 2 - 1, classComboBox.Size.Height);
classComboBox.Size = comboBoxSize;
membersComboBox.Location = new Point(classComboBox.Bounds.Right + 2, classComboBox.Bounds.Top);
membersComboBox.Size = comboBoxSize;
}
void MeasureComboBoxItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
if (e.Index >= 0) {
ComboBoxItem item = (ComboBoxItem)comboBox.Items[e.Index];
SizeF size = e.Graphics.MeasureString(item.ToString(), font);
e.ItemWidth = (int)size.Width;
e.ItemHeight = (int)Math.Max(size.Height, CodeCompletionProvider.ImagesProvider.ImageList.ImageSize.Height);
}
}
}
}