Bookstore

Recent

Author Topic: PseudoPartialUnit  (Read 4008 times)

PascalDragon

  • Hero Member
  • *****
  • Posts: 1088
  • Compiler Developer
Re: Split Unit
« Reply #60 on: March 20, 2020, 09:34:58 am »
Or at least be more selective about who you engage in a pissing contest.

 8-) ;D

Otto

  • Full Member
  • ***
  • Posts: 171
Re: Split Unit
« Reply #61 on: March 20, 2020, 10:08:25 am »
@soerensen3

Thank you for adapting your project pasunitmerge so that it can work on Windows 10 64bit.

Otto.
« Last Edit: March 20, 2020, 10:11:12 am by Otto »
Kind regards.
[I'm not a native English speaker.]

Otto

  • Full Member
  • ***
  • Posts: 171
Re: Split Unit
« Reply #62 on: March 20, 2020, 11:23:44 am »
Hello everyone.

I adapted my "do-nothing example" so that it could work with the soerensen3 project. It is not yet a strict version, there are changes to be made so that it can be considered suitable to meet the version of the OOP implementation commonly used in FPC.

I repeat that the example is for the sole purpose of discussing the usefulness of PartialUnits. As surely already understood by all, it refers to a way to replicate the implementation, including the logic used to position the events declaration, which Lazarus uses in the RAD.

Starting with two separate PartialUnits: "PUnitMain_COD.pp" and "PUnitMain_LFM.pp", which respectively correspond to the part dedicated to the code and the part dedicated to the GUI (the .lfm file) we get the file "UnitMain.pas" which is compilable with the FPC without making any further changes. This is possible by running the soerensen3 program with the following parameters:

Code: Bash  [Select]
  1. pasunitmerge PUnitMain_COD.pp PUnitMain_LFM.pp -o UnitMain.pas

"PUnitMain_COD.pp"
Code: Pascal  [Select]
  1. unit unitMain;    // PseudoPartial_unitMain
  2.  
  3.     {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     BtnClose: TButton;
  16.     Panel1: TPanel;
  17.     procedure BtnCloseClick(Sender: TObject);
  18.     procedure FormCreate(Sender: TObject);  // PseudoPartial_FormCreate
  19.     procedure InitializeLayaut(Sender: TObject); (* forward; *)// PseudoPartial_FormCreate
  20.   private
  21.  
  22.   public
  23.  
  24.   end;
  25.  
  26. var
  27.   Form1: TForm1;
  28.  
  29. implementation
  30.  
  31.     {$R *.lfm}
  32.  
  33. { TForm1 }
  34.  
  35. procedure TForm1.BtnCloseClick(Sender: TObject);
  36. begin
  37.   Close;
  38. end;
  39.  
  40. procedure TForm1.FormCreate(Sender: TObject);   // PseudoPartial_FormCreate
  41. begin
  42.   Form1.InitializeLayaut(self);   // PseudoPartial_InitializeLayaut
  43. end;     // PseudoPartial_FormCreate
  44.  
  45. end.     // PseudoPartial_unitMain    
  46.  

"PUnitMain_LFM.pp"
Code: Pascal  [Select]
  1. unit unitMain;        // PseudoPartial_unitMain
  2.  
  3.     {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Controls;
  9.  
  10. (*
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     procedure InitializeLayaut(Sender: TObject);  // PseudoPartial_FormCreate
  17.   private
  18.  
  19.   public
  20.  
  21.   end;
  22.  *)
  23.  
  24. // var
  25.  
  26. implementation
  27.  
  28. { TForm1 }
  29.  
  30. procedure TForm1.InitializeLayaut(Sender: TObject);
  31. // PseudoPartial_InitializeLayaut
  32. begin
  33.  
  34.   // Component serialized as Pascal - Begin
  35.   // Format version 1
  36.   Name := 'Form1';
  37.   Panel1 := TPanel.Create(Self);
  38.   BtnClose := TButton.Create(Self);
  39.   Left := 338;
  40.   Height := 512;
  41.   Top := 137;
  42.   Width := 512;
  43.   BorderStyle := bsNone;
  44.   Caption := 'Form1';
  45.   ClientHeight := 512;
  46.   ClientWidth := 512;
  47.   OnCreate := @FormCreate;
  48.   Position := poDesktopCenter;
  49.   LCLVersion := '2.0.6.0';
  50.   with Panel1 do
  51.   begin
  52.     Name := 'Panel1';
  53.     Left := 0;
  54.     Height := 512;
  55.     Top := 0;
  56.     Width := 512;
  57.     Anchors := [akTop..akBottom];
  58.     ClientHeight := 512;
  59.     ClientWidth := 512;
  60.     Color := clOlive;
  61.     ParentColor := False;
  62.     TabOrder := 0;
  63.     Parent := Self;
  64.     with BtnClose do
  65.     begin
  66.       Name := 'BtnClose';
  67.       Left := 432;
  68.       Height := 25;
  69.       Top := 8;
  70.       Width := 75;
  71.       Caption := 'Close';
  72.       OnClick := @BtnCloseClick;
  73.       TabOrder := 0;
  74.       Parent := Panel1;
  75.     end;
  76.   end;
  77.   // Component serialized as Pascal - End
  78.  
  79. end;  // PseudoPartial_InitializeLayaut
  80.  
  81. end.  // PseudoPartial_unitMain
  82.  

"UnitMain.pas"
Code: Pascal  [Select]
  1. unit UnitMain;
  2.  
  3. interface
  4.  
  5. uses
  6.   Classes,
  7.   Controls,
  8.   Dialogs,
  9.   ExtCtrls,
  10.   Forms,
  11.   Graphics,
  12.   StdCtrls,
  13.   SysUtils;
  14.  
  15. // UnitMain_COD -->
  16. type
  17.  
  18.   { TForm1 }
  19.  
  20.   TForm1 = class(TForm)
  21.     BtnClose: TButton;
  22.     Panel1: TPanel;
  23.     procedure BtnCloseClick(Sender: TObject);
  24.     procedure FormCreate(Sender: TObject);  // PseudoPartial_FormCreate
  25.     procedure InitializeLayaut(Sender: TObject); (* forward; *) // PseudoPartial_FormCreate
  26.   private
  27.  
  28.   public
  29.  
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34. // <--UnitMain_COD
  35.  
  36. // UnitMain_LFM -->
  37. (*
  38. type
  39.  
  40.   { TForm1 }
  41.  
  42.   TForm1 = class(TForm)
  43.     procedure InitializeLayaut(Sender: TObject);  // PseudoPartial_FormCreate
  44.   private
  45.  
  46.   public
  47.  
  48.   end;
  49.  *)
  50.  
  51. // var
  52. // <--UnitMain_LFM
  53.  
  54. implementation
  55.  
  56. // UnitMain_COD -->
  57. procedure TForm1.BtnCloseClick(Sender: TObject);
  58. begin
  59.   Close;
  60. end;
  61.  
  62. procedure TForm1.FormCreate(Sender: TObject);   // PseudoPartial_FormCreate
  63. begin
  64.   Form1.InitializeLayaut(self);   // PseudoPartial_InitializeLayaut
  65. end;     // PseudoPartial_FormCreate
  66. // <--UnitMain_COD
  67.  
  68. // UnitMain_LFM -->
  69. procedure TForm1.InitializeLayaut(Sender: TObject);
  70. // PseudoPartial_InitializeLayaut
  71. begin
  72.  
  73.   // Component serialized as Pascal - Begin
  74.   // Format version 1
  75.   Name := 'Form1';
  76.   Panel1 := TPanel.Create(Self);
  77.   BtnClose := TButton.Create(Self);
  78.   Left := 338;
  79.   Height := 512;
  80.   Top := 137;
  81.   Width := 512;
  82.   BorderStyle := bsNone;
  83.   Caption := 'Form1';
  84.   ClientHeight := 512;
  85.   ClientWidth := 512;
  86.   OnCreate := @FormCreate;
  87.   Position := poDesktopCenter;
  88.   LCLVersion := '2.0.6.0';
  89.   with Panel1 do
  90.   begin
  91.     Name := 'Panel1';
  92.     Left := 0;
  93.     Height := 512;
  94.     Top := 0;
  95.     Width := 512;
  96.     Anchors := [akTop..akBottom];
  97.     ClientHeight := 512;
  98.     ClientWidth := 512;
  99.     Color := clOlive;
  100.     ParentColor := False;
  101.     TabOrder := 0;
  102.     Parent := Self;
  103.     with BtnClose do
  104.     begin
  105.       Name := 'BtnClose';
  106.       Left := 432;
  107.       Height := 25;
  108.       Top := 8;
  109.       Width := 75;
  110.       Caption := 'Close';
  111.       OnClick := @BtnCloseClick;
  112.       TabOrder := 0;
  113.       Parent := Panel1;
  114.     end;
  115.   end;
  116.   // Component serialized as Pascal - End
  117.  
  118. end;  // PseudoPartial_InitializeLayaut
  119. // <--UnitMain_LFM
  120.  
  121. end.
  122.  



I hope that I have explained myself in an understandable way and that I have not made any serious mistakes during the translation. Any opinion or criticism, even in languages other than English, is well accepted.

Otto.
Kind regards.
[I'm not a native English speaker.]

ASBzone

  • Sr. Member
  • ****
  • Posts: 323
  • Automation leads to relaxation...
    • BrainWaveCC Utilities
Re: Split Unit
« Reply #63 on: March 23, 2020, 04:06:05 pm »
Hi!

I do it the simpler way since I returned from Modula2 to Pascal:

Whenever I write a "begin" I add at once after the "end" the reason.
So the last lines of a procedure look like:

     end; // if <> transparent
  end; // for x
 end; // for y
end; // proc

Winni

There is much wisdom in this.

I used to do this at one time (a long time ago), and stopped.   I should pick it back up again. :)
-ASB: https://www.BrainWaveCC.com

Lazarus v2.0.7 r62681 / FPC v3.2.0-beta-r44391 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 1909 (Build 18363.720)
Other Systems: Windows 10 Pro x64, Version 1909 or greater

ASBzone

  • Sr. Member
  • ****
  • Posts: 323
  • Automation leads to relaxation...
    • BrainWaveCC Utilities
Re: Split Unit
« Reply #64 on: March 23, 2020, 04:12:09 pm »
Also there is the outline feature if you use Lazarus: https://wiki.freepascal.org/Lazarus_IDE_Tools#Outline

Nice!!

I really have to take some time and dig through all the options...
-ASB: https://www.BrainWaveCC.com

Lazarus v2.0.7 r62681 / FPC v3.2.0-beta-r44391 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 1909 (Build 18363.720)
Other Systems: Windows 10 Pro x64, Version 1909 or greater

kupferstecher

  • Sr. Member
  • ****
  • Posts: 361
Re: Split Unit
« Reply #65 on: March 24, 2020, 01:35:19 pm »
Starting with two separate PartialUnits: "PUnitMain_COD.pp" and "PUnitMain_LFM.pp", which respectively correspond to the part dedicated to the code and the part dedicated to the GUI (the .lfm file) we get the file "UnitMain.pas" which is compilable with the FPC without making any further changes. This is possible by running the soerensen3 program with the following parameters:
I'm not sure what is your final target, but if you use a seperate program to merge split units, you probably get trouble with code navigation and code completion in the IDE.

What I could think about of being a useful feature is that a Class could be declared as 'friend' with an other class which would allow to access e.g. protected fields of that other class directly. With this feature two units could be linearly entangled (which imho is ok) and still the encapsulation to outside units would be kept, as only public declarations are accessible to third units. But this would mean additional complexitivity to the language, I'm not sure if it would be worth it.

Hypothetical Example:
Code: Pascal  [Select]
  1. Type TFoo = class(friends TThread)
  2.   Procedure DoSomething;
  3. end;
  4.  
  5. IMPLEMENTATION
  6.  
  7. Procedure DoSomething
  8. begin
  9.   MyBusyThread.Synchronize(@SthElse);  //Synchronize is a protected procedure, thus it wouldn't be accessible here*
  10. end;

* Yes, it's not the best example as there is a public version of Synchronize...


Otto

  • Full Member
  • ***
  • Posts: 171
Re: PseudoPartialUnit
« Reply #66 on: March 25, 2020, 05:01:02 pm »
Thank you kupferstecher for your response.
I am very pleased to know that there are other developers interested in this topic.

if you use a seperate program to merge split units, you probably get trouble with code navigation and code completion in the IDE.
At the moment what you say is very likely; but I'm trying to increase feature integration with Lazarus-IDE. 
Quote
What I could think about of being a useful feature is that a Class could be declared as 'friend' with an other class which would allow to access e.g. protected fields of that other class directly. With this feature two units could be linearly entangled (which imho is ok) and still the encapsulation to outside units would be kept, as only public declarations are accessible to third units. But this would mean additional complexitivity to the language, I'm not sure if it would be worth it.
Your proposal looks very interesting; from an initial evaluation I think can be integrated into the abstract concept of PartialUnit. After studying and thinking more, I will ask you for more details.
Quote
I'm not sure what is your final target
At this stage, the ultimate purpose of the project is still very difficult to describe, I have yet to prepare a clear and organic speech. Generally speaking, what I would like to achieve is facilitation in the introduction of new features into the Lazarus-IDE/FPC programming environment avoiding, where possible, compiler changes.
Implementing PartialUnits might e.g. help when converting code from other programming languages. It would be possible to deal separately with the different implementations of OOP (or other programming paradigms) that are unique to each programming language.
A hint of what I'm saying is present in the code I reported in my previous post.
In particular, we could use this method to replace the file "Lazarus Form" (.lfm file) with Pascal Object code. The various declarations and implementations of the code could be distributed in accordance with the preferred OOP logic: in fact, the PartialUnits, in my opinion, are not to be considered separate Units, but a single unit deployed in different blocks of code. As you can see from the example, both have the same name as "unitMain". I have not yet adapted the merging code (pasunitmerge) to be able to respect the distribution of the code to my liking e.g. the definition of the InitializeLayaut method would go all over in the file "PunitMain_LFM.pp", for now I have only added the part of the code  commented on).

There are components that are used to convert the "Lazarus Form files" into Pascal code (in this thread I learned how to use it thanks to wp). For now they do not do the job completely automatically, but they could be refined and adapted to produce a reversible conversion (from pascal code to lfm script and vice versa).

The advantage would not be to be underestimated, you could edit complex GUIs directly in pascal code and have the ".lfm" file regenerated for Lazarus. Also I think (I haven't checked yet and so the probability that I'm wrong is very high) that the compiler still needs a pre-conversion from ".lfm files" to pascal code before FPC can compile the project.
I believe that what I have said is achievable without having to make significant changes to the Lazarus-IDE.

(-: Thank you for having the patience to read my post. :-)

Otto.


Kind regards.
[I'm not a native English speaker.]

kupferstecher

  • Sr. Member
  • ****
  • Posts: 361
Re: PseudoPartialUnit
« Reply #67 on: March 25, 2020, 11:46:13 pm »
Hello Otto,

At the moment what you say is very likely; but I'm trying to increase feature integration with Lazarus-IDE.
If you have split units that represent one unit then you can access all variables which are in the other part of the split unit. So the codetools have to recognise both units as one, as well. I have no insight to that, but i guess it's quite difficult to achive, even more if you can't include it as standard installation. The debugger would be an other topic.

--
Another idea: Use the include file as basis and add IDE features so that the include file is recognised and shown as part of the whole unit. If the include file is recognized, you could also show e.g. the interface part in the editor window of the included file. The advantage would be that you don't need further utilities, preprocessor etc.
It would be just a different way of displaying the files.
But no idea how to implement something like that.

--
A (compiler) feature that i miss is a forwarding mechanism of units in "uses". So that a library can consist of several units and the library's main unit begins like that
Code: Pascal  [Select]
  1. unit MyLib;
  2. publishes MyLibPart1,MyLibPart2,MyLibPart3;
Then when using the library it would be enough to write
Code: Pascal  [Select]
  1. uses MyLib;
and all forwarded units would be implicitly used/accessible.
But probably there are reasons for not having that :-)


Otto

  • Full Member
  • ***
  • Posts: 171
Re: PseudoPartialUnit
« Reply #68 on: March 26, 2020, 05:57:34 pm »
Hi kupferstecher.

If you have split units that represent one unit then you can access all variables which are in the other part of the split unit. So the codetools have to recognise both units as one, as well. I have no insight to that, but i guess it's quite difficult to achive, even more if you can't include it as standard installation. The debugger would be an other topic.
In fact, this is a very complex problem to solve. At this early stage I was considering using an external component that can store links between the WholeUnit and the various PartialUnits. The debugger might also work with this system. In practice, for FPC and Lazarus everything would remain the same, but the developer could use the PartialUnits that would remain synchronized with WholeUnit.

Quote
Another idea: Use the include file as basis and add IDE features so that the include file is recognised and shown as part of the whole unit. If the include file is recognized, you could also show e.g. the interface part in the editor window of the included file. The advantage would be that you don't need further utilities, preprocessor etc.
It would be just a different way of displaying the files.
But no idea how to implement something like that.
It is possible that using the include directive correctly can improve the linking phase. But I have to admit that I'm not sure I fully understood your idea. 

Quote
A (compiler) feature that i miss is a forwarding mechanism of units in "uses".

Forwarding mechanism must, in some way, certainly be used to enable the implementation of PartialUnits.

Thank you very much for your interest. Discussing with other programmers is always very helpful and helps to evaluate further possibilities.

Otto.
Kind regards.
[I'm not a native English speaker.]

kupferstecher

  • Sr. Member
  • ****
  • Posts: 361
Re: PseudoPartialUnit
« Reply #69 on: March 26, 2020, 07:07:46 pm »
Quote
Another idea: Use the include file as basis and add IDE features so that the include file is recognised and shown as part of the whole unit. If the include file is recognized, you could also show e.g. the interface part in the editor window of the included file. The advantage would be that you don't need further utilities, preprocessor etc.
It would be just a different way of displaying the files.
But no idea how to implement something like that.
[...] I'm not sure I fully understood your idea.

The idea was to use what the language provides, i.e. the include files and display them like your partial units. The IDE already can handle include files very well, with code completion and so on. You could change the way of displaying the include file like I tried to show below.

Example:

Code: Pascal  [Select]
  1. unit unitMain;
  2. interface
  3. uses
  4.   Classes, SysUtils
  5.  
  6. type TForm1 = class(TForm)
  7.     procedure FormCreate(Sender: TObject);
  8.     procedure InitializeLayout(Sender: TObject);  //Part of the include
  9.   end;
  10.  
  11. implementation
  12. {$I unitMain_subpart.inc}  //here the content of the "partial unit", i.e. of the include file, could be shown by code folding in a grayed out, readonly way.
  13.  
  14. procedure TForm1.FormCreate(Sender: TObject);
  15. begin
  16.   Form1.InitializeLayout(self);
  17. end;
  18.  end.

unitMain_subpart.inc

Code: Pascal  [Select]
  1. (*unit unitMain;   //Here the header could be included in grayed out, read-only way.
  2. interface
  3. uses
  4.   Classes, SysUtils
  5.  
  6. type TForm1 = class(TForm)
  7.     procedure FormCreate(Sender: TObject);
  8. procedure InitializeLayout(Sender: TObject);
  9.   end;
  10.  
  11. implementation *)
  12.  
  13. procedure TForm1.InitializeLayout(Sender: TObject);
  14. begin
  15.   ...
  16. end;


Otto

  • Full Member
  • ***
  • Posts: 171
Re: PseudoPartialUnit
« Reply #70 on: March 26, 2020, 09:58:47 pm »
Hi kupferstecher.

The idea was to use what the language provides, i.e. the include files and display them like your partial units. The IDE already can handle include files very well, with code completion and so on. [...]
Great tip.
I started the thread using the {$include …} directives. The fact that with the includes directives it is so easy to navigate within the code denotes how well Lazarus is done. In the post #23 I had reported an example just to explain what I wanted to achieve without altering anything in FPC, reporting the code not yet acceptable commented.

The suggestion leads me to believe that the feasibility of the abstract concept of PartialUnits is closer. In fact, instead of creating a synchronizer for PartialUnits and the Unit-Integer, I could only create a converter between PartialUnits and IncludeFiles (code blocks linked by the use of $include directives). The work would be considerably simpler and certainly at an early stage even easier to describe. Later, if we wanted to integrate into the IDE or an external component, it could always be adapted to future needs.

These days I will try to write a descriptive text in order to evaluate the possibility of creating an open source project. However, I don't have much experience in open source projects.

Thanks again kupferstecher.

Otto.
Kind regards.
[I'm not a native English speaker.]

soerensen3

  • Full Member
  • ***
  • Posts: 197
Re: PseudoPartialUnit
« Reply #71 on: March 27, 2020, 11:10:12 pm »
How about this skeleton:

Unit1.Partial1:
Code: Pascal  [Select]
  1. {%region /fold}
  2. {$IFNDEF INCLUDE}
  3. {%endregion}
  4.  
  5. unit Unit1.Partial1;
  6.  
  7. {$mode objfpc}{$H+}
  8.  
  9. interface
  10.  
  11. uses
  12.   Classes,
  13.   SysUtils;
  14.  
  15. {%region /fold}
  16. {$DEFINE INCLUDE_INTF}
  17. {$ENDIF}
  18.  
  19. {$IFDEF INCLUDE_INTF}
  20. {%endregion}
  21.  
  22. // interface here
  23.  
  24. {%region /fold}
  25. {$ENDIF}
  26. {$IFNDEF INCLUDE}
  27. {%endregion}
  28.  
  29. implementation
  30.  
  31. {%region /fold}
  32. {$DEFINE INCLUDE_IMPL}
  33. {$ENDIF}
  34. {$IFDEF INCLUDE_IMPL}
  35. {%endregion}
  36.  
  37. // implementation here
  38. {%region /fold}
  39. {$ENDIF}
  40. {$IFNDEF INCLUDE}
  41. {%endregion}
  42. end.
  43.  
  44. {%region /fold}
  45. {$ENDIF}
  46. {%endregion}

Unit1:

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils,
  9.   fpjson,
  10.   Math,
  11.   LazUTF8,
  12.   LazFileUtils;
  13.  
  14. {$DEFINE INCLUDE}
  15. {$DEFINE INCLUDE_INTF}
  16. {$INCLUDE Unit1.lib.inc}
  17. {$UNDEF INCLUDE}
  18. {$UNDEF INCLUDE_INTF}
  19.  
  20. implementation
  21.  
  22. {$DEFINE INCLUDE}
  23. {$DEFINE INCLUDE_IMPL}
  24. {$INCLUDE Unit1.lib.inc}
  25. {$UNDEF INCLUDE}
  26. {$UNDEF INCLUDE_IMPL}
  27.  
  28. end.

Unit1.lib.inc:
Code: Pascal  [Select]
  1. {$INCLUDE Unit1.Partial1.pas}
  2. //add other partial units here

It will work as a normal unit but if you want to merge it you just put Unit1 in the uses section. If you need forward declarations across files then of course you can't use the partial unit in a uses section. It does not break code completion completely however if you work with the partial unit.
Lazarus 1.9 with FPC 3.0.4
Target: Manjaro Linux 64 Bit (4.9.68-1-MANJARO)

Otto

  • Full Member
  • ***
  • Posts: 171
Re: PseudoPartialUnit
« Reply #72 on: March 28, 2020, 09:23:27 pm »
Thank you soerensen3.
I'm checking to see if I can use your suggestion, I'll let you know.
Otto.
Kind regards.
[I'm not a native English speaker.]

Otto

  • Full Member
  • ***
  • Posts: 171
Re: PseudoPartialUnit
« Reply #73 on: March 29, 2020, 06:01:21 pm »
Hello everyone.

Good news, the suggestion of soerensen3 proved very useful.
I prepared a simple example based on the skeleton proposed by soerensen3, to see if implementing the abstract concept of PartialUnit kept the essential features of the Lazarus-IDE editor. The result was positive. The code completion is working, the navigation in the code works correctly. The Code Explorer correctly displays the PartialUnits as if it were a single Unit and allows for proper and fast navigation. I would like to mention that the PartialUnit is defined as: a single unit fragmented into separate parts of code.

Warning: The following code is intended to verify that code completion works when using Units deployed in different files. It is not intended to be useful for different purposes.

expu_main.pas
Code: Pascal  [Select]
  1. unit ExPU_Main;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils,
  9.   fpjson,
  10.   //Math,
  11.   //LazUTF8,
  12.   LazFileUtils;
  13.  
  14. {%region Interface_PartialUnit}
  15. {$DEFINE INCLUDE}
  16. {$DEFINE INCLUDE_INTF}
  17. {$INCLUDE ExPU.lib.inc}
  18. {$UNDEF INCLUDE}
  19. {$UNDEF INCLUDE_INTF}
  20. {%endregion}
  21.  
  22. OpR = Class(TObject)
  23.   Private
  24.   public
  25.     class Function Aum(iVar, iTo:integer): integer;  static;
  26.     class Function Dim(iVar:integer; iTo:integer): integer;  static;
  27.     class Function Mul(iVar:integer; iTo:integer): integer;  static;
  28.   end;
  29.  
  30. var
  31.   a : integer = 5;
  32.  
  33. implementation
  34.  
  35. {%region Implementation_PartialUnit}
  36. {$DEFINE INCLUDE}
  37. {$DEFINE INCLUDE_IMPL}
  38. {$INCLUDE ExPU.lib.inc}
  39. {$UNDEF INCLUDE}
  40. {$UNDEF INCLUDE_IMPL}
  41. {%endregion}
  42.  
  43. { Opex }
  44.  
  45. class function Opex.Dim(iVar:integer):integer;
  46. begin
  47.   result := iVar-1;
  48. end;
  49.  
  50. { OpR }
  51.  
  52. class Function OpR.Mul(iVar:integer; iTo:integer): integer;
  53. begin
  54.   result := iVar*iTo;
  55. end;
  56.  
  57. end.                    
  58.  

ExPU.Partial1.pas
Code: Pascal  [Select]
  1. {%region PartialUnit_Begin}
  2. {$IFNDEF INCLUDE}
  3. {%endregion}
  4.  
  5. unit ExPU.Partial1;
  6.  
  7. {$mode objfpc}{$H+}
  8.  
  9. interface
  10.  
  11. uses
  12.   Classes,
  13.   SysUtils;
  14.  
  15. {%region interface_Begin}
  16. {$DEFINE INCLUDE_INTF}
  17. {$ENDIF}
  18.  
  19. {$IFDEF INCLUDE_INTF}
  20. {%endregion}
  21.  
  22. // interface here
  23. Type
  24.   Opex = Class(TObject)
  25.   Private
  26.     //class var myprivatea : integer;
  27.   public
  28.     //class Function GetA : Integer;  static;
  29.     //class Procedure SetA(AValue : Integer); static;
  30.     //function Aumenta(iVar:integer):integer;
  31.     class Function Aum(iVar:integer): integer;  static;
  32.     class Function Dim(iVar:integer): integer;  static;
  33.   end;
  34.  
  35. {%region interface_End}
  36. {$ENDIF}
  37. {$IFNDEF INCLUDE}
  38. {%endregion}
  39.  
  40. implementation
  41.  
  42. {%region implementation_Begin}
  43. {$DEFINE INCLUDE_IMPL}
  44. {$ENDIF}
  45. {$IFDEF INCLUDE_IMPL}
  46. {%endregion}
  47. // implementation here
  48.  
  49. function Aum(iVar:integer):integer;
  50. begin
  51.   result := iVar+1;
  52. end;
  53.  
  54. { Opex }
  55.  
  56. class function Opex.Aum(iVar:integer):integer;
  57. begin
  58.   //result:=Aum(iVar); //
  59.   result := iVar+1;
  60. end;
  61.  
  62. { OpR }
  63.  
  64. class Function OpR.Aum(iVar:integer; iTo:integer): integer;
  65. begin
  66.   result:=iVar+iTo;
  67. end;
  68.  
  69. class Function OpR.Dim(iVar, iTo:integer): integer;
  70. begin
  71.   result:=iVar-iTo;
  72. end;
  73.  
  74. {%region implementation_End}
  75. {$ENDIF}
  76. {$IFNDEF INCLUDE}
  77. {%endregion}
  78.  
  79. end.
  80.  
  81. {%region PartialUnit_End}
  82. {$ENDIF}
  83. {%endregion}
  84.  

expu.costanti.pas

Code: Pascal  [Select]
  1. {%region PartialUnit_Begin}
  2. {$IFNDEF INCLUDE}
  3. {%endregion}
  4.  
  5. unit expu.costanti;    // test Name
  6.  
  7. {$mode objfpc}{$H+}
  8.  
  9. interface
  10.  
  11. uses
  12.   Classes,
  13.   SysUtils;
  14.  
  15. {%region interface_Begin}
  16. {$DEFINE INCLUDE_INTF}
  17. {$ENDIF}
  18. {$IFDEF INCLUDE_INTF}
  19. {%endregion}
  20.  
  21. // interface here
  22. Type
  23.   Costanti = Class(TObject)
  24.   Private
  25.   public
  26.     const Val1:byte=$0A;
  27.           Val2:byte=42;
  28.           Val3:byte=13;
  29.   end;
  30.  
  31. {%region interface_End}
  32. {$ENDIF}
  33. {$IFNDEF INCLUDE}
  34. {%endregion}
  35.  
  36. implementation
  37.  
  38. {%region implementation_Begin}
  39. {$DEFINE INCLUDE_IMPL}
  40. {$ENDIF}
  41. {$IFDEF INCLUDE_IMPL}
  42. {%endregion}
  43. // implementation here
  44. {%region implementation_End}
  45. {$ENDIF}
  46. {$IFNDEF INCLUDE}
  47. {%endregion}
  48.  
  49. end.
  50. {%region PartialUnit_End}
  51. {$ENDIF}
  52. {%endregion}
  53.  

Now the possibility of obtaining PartialUnits is more concrete.

Thanks again soerensen3 and kupferstecher.

Otto.
Kind regards.
[I'm not a native English speaker.]