AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Interface-Unterstützung

Ein Thema von stahli · begonnen am 2. Sep 2017 · letzter Beitrag vom 25. Mai 2018
Antwort Antwort
Seite 3 von 7     123 45     Letzte »    
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#21

AW: Interface-Unterstützung

  Alt 3. Sep 2017, 13:50
Hallo Stahli,

geht es dir bei dem Tool nur um das Modelling, oder auch das Debugging ?
Mich stört nämlich ziemlich das man nicht immer sauber in Interfaces reindebuggen kann,
also weil es wohl die aktuele Implementation nicht finden kann.
Da wäre mir ein Tool oder eine Lösung auch willkommen.

Rollo
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#22

AW: Interface-Unterstützung

  Alt 3. Sep 2017, 13:59
Das Problem bei Automatisch/Implizit:
Zitat:
property X: Interger read write;
Ist "write" der Name des Getters?

Und wie sieht die implizite Implementation aus?
Gut, den Namen "SetX" hätten wir schonmal, aber was ist mit der Signatur?
Delphi-Quellcode:
procedure SetX(aValue: Integer);
procedure SetX(const aValue: Integer);
procedure SetX(aValue: Integer); stdcall;
procedure SetX(const aValue: Integer); stdcall;
...
$2B or not $2B

Geändert von himitsu ( 3. Sep 2017 um 14:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#23

AW: Interface-Unterstützung

  Alt 3. Sep 2017, 14:11
@Rollo62

Das Debugging würde meine Möglichkeiten übersteigen.
Das wird wohl nur Emba können.

Mein Tool soll lediglich verkürzte Schreibweisen korrigieren.
Aus

Delphi-Quellcode:
// MyIntf.pas
...
IMyintf = interface
  prop X:Integer;
  prop Y:Integer ro; // read only
  prop Z:Integer wo; // write only
end;
soll es die notwendigen Getter und Setter definieren und aus

Delphi-Quellcode:
// MyClass.pas
...
TMyintf = class(TBaseClass, IMyIntf)
end;
soll es die erforderlichen Propertys und Methoden entsprechend der eingebunden Interfaces erstellen und alles (incl. des Implemantationsteils) vernünftig strukturieren.


@himitsu

Statt bzw. zusätzlich zu "ro" und wo" könnte man ja noch "c" für "const" und "s" für "stdcall" vorsehen.
Wenn das Prinzip funktioniert, dann ist man da sicher flexibel.

Ich bastle gerade einen Parser(Light). Dann werden die gefunden Teile strukturiert gesammelt und später neu zusammengebaut.
Je nach Aufwand kann das sicher auch mit komplexeren Anforderungen umgehen.

Als externes Tool kann ich das sicher realisieren.
Schwieriger wird wohl, das in die IDE einzubinden. Es wäre so etwas wie ein Quelltextformatierer.

Er würde die Unit zerlegen und neu zusammenbauen.
Welche Interfaces eine Klasse verwendet, weiß ich schon.
Das Tool müsste aber jetzt noch die Units ermitteln können, welche diese Interfaces deklarieren.
Dazu müsste wohl die Funktion genutzt werden, die durch Ctrl+Click in die Unit springt.
Damit kenne ich mich nicht aus.

Dann müssten evt. die Interface-Units überarbeitet werden (s.o.), die Interface-Deklaration übernommen werden und dann kann die Klasse optimiert werden.

Vorerst reduziere ich das ganze halt mal auf ein externes Tool.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli ( 3. Sep 2017 um 14:32 Uhr)
  Mit Zitat antworten Zitat
Wosi

Registriert seit: 29. Aug 2007
59 Beiträge
 
#24

AW: Interface-Unterstützung

  Alt 3. Sep 2017, 21:22
Bevor du dich an einem Parser versuchst, solltest du lieber auf DelphiAST (https://github.com/RomanYankovsky/DelphiAST) zurückgreifen.

Wenn es dir um das Schreiben von Code geht kannst du auch Visual Studio Code + OmniPascal nehmen. Die automatische Implementierung von Interfaces, sowie Snippets und multi Cursor Unterstützung helfen bei der Schreibarbeit: https://twitter.com/OmniPascal/statu...53751267790849
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#25

AW: Interface-Unterstützung

  Alt 3. Sep 2017, 22:29
Danke für den Tipp.
Ich habe allerdings einen eigenen Parser aus einem anderen Projekt und kann den hier verwenden.

Ein Teil der Interface-Aufbereitung geht schon:
Delphi-Quellcode:
...
type

  IsoNameObj = interface;

  iMyBaseIntf = Interface
    prop BaseProp:integer;
  end;

  IMyIntf = interface(IMyBaseIntf)
    procedure DoA;
    prop A:string c s;
    prop B:string ro;
    prop C:string wo c s;
    prop D:string sg;
    prop E:string ss c;
    function GetA:Integer;
  end;

  IMyIntf2 = interface(IMyBaseIntf)
    prop X:string c s;
    prop Y:string ro;
    function GetX:Integer;
  end;

  IMyIntf3 = interface
    procedure DoZ;
    prop Z:string c;
    function GetZ:Integer;
  end;

  TsoNotifyEvent = procedure(const Sender: IInterface) of object;

  IsoSystem = interface;
  IsoProject = interface;
  IsoPropertyDef = interface;
  IsoMethodeDef = interface;
  IsoClass = interface
...
wird zu:
Delphi-Quellcode:
...
type

  IsoNameObj = interface;

  iMyBaseIntf = Interface
        function _get_BaseProp: integer;
        procedure _set_BaseProp(aValue: integer);
        property BaseProp: integer read _get_BaseProp write _set_BaseProp;
  end;

  IMyIntf = interface(IMyBaseIntf)
    procedure DoA;
        function _get_A: string; stdcall;
        procedure _set_A(const aValue: string); stdcall;
        property A: string read _get_A write _set_A;
        function _get_B: string;
        property B: string read _get_B;
        procedure _set_C(const aValue: string); stdcall;
        property C: string write _set_C;
        function _get_D: string; stdcall;
        procedure _set_D(aValue: string);
        property D: string read _get_D write _set_D;
        function _get_E: string;
        procedure _set_E(const aValue: string); stdcall;
        property E: string read _get_E write _set_E;
    function GetA:Integer;
  end;

  IMyIntf2 = interface(IMyBaseIntf)
        function _get_X: string; stdcall;
        procedure _set_X(const aValue: string); stdcall;
        property X: string read _get_X write _set_X;
        function _get_Y: string;
        property Y: string read _get_Y;
    function GetX:Integer;
  end;

  IMyIntf3 = interface
    procedure DoZ;
        function _get_Z: string;
        procedure _set_Z(const aValue: string);
        property Z: string read _get_Z write _set_Z;
    function GetZ:Integer;
  end;

  TsoNotifyEvent = procedure(const Sender: IInterface) of object;

  IsoSystem = interface;
  IsoProject = interface;
  IsoPropertyDef = interface;
  IsoMethodeDef = interface;
  IsoClass = interface;
...

Der Parser erkennt Interfacedeklarationen und kann auch Forward-Deklarationen unterscheiden.
Nur die richtigen Interfaces scant und optimiert er.

Die generierten Zeilen habe ich hier mal eingerückt.

Jetzt will ich noch regeln, dass Typänderungen von Propertys automatisch in vorhanden Gettern und Settern angepasst werden.
Namensänderungen von Membern können dann nicht automatisch bearbeitet werden (das wäre höchstens möglich für Getter und Setter von Propertys, aber das wäre den Aufwand wohl nicht wert).

Die Interface-Member werden als Objekte gespeichert und an die Klassen übergeben.
Dort wird dann noch geprüft, ob die dortigen Member korrekt sind. Sonst wird die Klasse angepasst und ggf. Propertys und Methoden erzeugt.

Anschließend wird die Unit sortiert.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli ( 3. Sep 2017 um 23:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#26

AW: Interface-Unterstützung

  Alt 5. Sep 2017, 00:21
Alle Sonderfälle kann man sicher nicht abdecken, aber jetzt kann man ein altes Property einfach durch ein neues überschreiben...

alt:
Delphi-Quellcode:
  iMyBaseIntf = Interface // mehrfache Methoden hier nur zum Test
    function _get_BaseProp: string;
    procedure _set_BaseProp(aTestS: string);
    prop BaseProp:integer; // überschreibt evtl. vorhandene Property sowie Getter und Setter
    function _get_BaseProp: Boolean;
    procedure _set_BaseProp(aTestB: Boolean);
    property BaseProp: Boolean read _get_BaseProp write _set_BaseProp;
  end;

neu:
Delphi-Quellcode:
  iMyBaseIntf = Interface
        function _get_BaseProp: integer;
        procedure _set_BaseProp(aValue: integer);
        property BaseProp: integer read _get_BaseProp write _set_BaseProp;
  end;

Der nächste Schritt soll sein, dass man einfach BaseProp: integer in BaseProp: Boolean ändern kann und dadurch Getter und Setter im Interface angepasst werden.

Die Klassen werden dann unabhängig von der Ausgangssituation an die aktuelle Interface-Deklaration angepasst.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#27

AW: Interface-Unterstützung

  Alt 5. Nov 2017, 23:12
Anbei mal eine erste Testversion, die schon mal zwei Units (_unit1 und _unit2) ordnet und sortiert.
In den zwei Memos links sind die Originale und rechts die Ergebnisse dargestellt.

Die beigefügten Units sind verstümmelte Units von mir.
Unit1 enthält einige Klassen und Unit2 für später die zugehörigen Interfaces (diese könnten aber dann auch direkt in der Unit1 deklariert sein).
Die Interfaces werden aktuell allerdings noch nicht berücksichtigt.

Die Unit1 wird aktuell vernünftig umsortiert.

Einige Dinge funktionieren noch nicht. Direkt fallen mir ein:
- class Variablen, Funktionen etc
- Embedded functions/procedures
- strict private etc
- overloads
- Klassen- und Interfacedeklarationen im Implementationsteil

Eine besondere Schwierigkeit beim Umsortieren sind Zeilenumbrüche und Kommentare mitten im Code.
Es kann schon sein, dass Eure Code-Styles aktuell nicht korrekt unterstützt werden.


Als nächstes will ich erst mal die oben schon erläuterte "prop"-Interpretation umsetzen. Für die Interfaces hatte ich das ja schon mal realisiert, muss das aber nochmal auf den neuen Parser anpassen.
Dann können z.B. durch
"prop MyProp:Integer rf wf;" ein Property mit privatem Feld und durch
"prop MyProp:Integer;" ein Property mit Getter und Setter (+privatem Feld) erzeugt werden.
Wenn der Property-Typ geändert wird, wird schlägt das automatisch auf die Getter, Setter und privaten Felder durch.

Außerdem sollen neue Deklarationen von Methoden im Implementationsteil entsprechende neuen Methoden erzeugen.
Änderungen von Parametern sollen in den Implementationsteil übernommen werden. Umbenennungen von Parametern könnte das Tool erkennen und im Methodenbody nachführen (das wäre das einzige wirkliche "Refactoring" durch das Tool).


Zum Schluss sollen dann alle Deklarationen in Interfaces automatisch in den Klassen realisert/angepasst werden, die dieses Interface verwenden.
Wenn z.B. eine Klasse nicht kompiliert und man das Tool startet, würden die notwendigen Deklarationen aus dem Interface in einer Standardform implementiert und können bei Bedarf noch überarbeitet werden.


Im Grunde wäre das Tool eine neue Klassenvervollständigung + Interface-Berücksichtigung + Unit-Neuordnung.


Die Frage ist, wie weit man das treiben will und soll.
Man könnte auch einen kompletten Code-Formatierer daraus bauen (wobei mir eigentlich der eingebaute reicht).
Vielleicht mit Ausrichtung der Punkte bei FluentInterfaces?

Habt Ihr dazu Bedarf/Meinungen?


In jedem Fall will ich das Tool später mal in die IDE integrieren.
Dazu wäre es cool, wenn ich die Interfaces-Units aus der Klassendeklaration finden könnte (also die Unit, die durch Ctrl+Click auf IMyIntf geöffnet wird).
Noch braucht es etwas Zeit bis dahin. Aber kennt sich damit jemand aus?
Miniaturansicht angehängter Grafiken
uo.png  
Angehängte Dateien
Dateityp: zip UnitOptimizer.zip (2,72 MB, 8x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli ( 6. Nov 2017 um 00:22 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#28

AW: Interface-Unterstützung

  Alt 7. Nov 2017, 12:55
Gibt´s da wirklich kein Interesse?

Wenn ich das so realisieren kann würde das m.E. eine große Schwäche der Delphi-IDE ausbessern und auch effektiver sein als der ModelMaker Code Explorer.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#29

AW: Interface-Unterstützung

  Alt 7. Nov 2017, 13:26
Was mir bei deinen Überlegungen fehlt, ist folgender Sachverhalt:
Die Klassen, die das zu refaktorierende Interface implementieren, müssen nicht zwangsläufig im gerade aktuell geladenen Projekt zu finden sein.
Ggf. sind die in einen anderen Projekt zu finden, welches auch dieses Interface verwendet. Oder sind in einer BPL oder DLL.
Oder sind gar keine Delphi-Klassen, sondern in irgendeiner anderen Sprache in einen anderen Modul implementiert.

Falls man wirklich mehr als drei Zeilen am Interface ändert, dann macht man Copy&Paste und tackert das in die Klasse rein und passt entsprechend an.
Vielleicht ist mein Leidensdruck auch nicht so hoch, weil sich relativ schnell eine fertige Property- und Methodendefinition feststeht.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#30

AW: Interface-Unterstützung

  Alt 7. Nov 2017, 13:47
Klassen in anderen Projekten werden natürlich nicht berücksichtigt.

Der Ablauf wäre folgender:

1) Interface überarbeiten
z.B. "prop MyIntf: Integer"
wodurch gleich auch Getter und Setter im Interface ergänzt werden.

2) Projekt kompilieren, und die Units, die nicht kompiliert werden können nacheinander durch das Tool optimieren lassen (z.B. Ctrl+Shift+O, wenn es als IDE-Experte implementiert ist).
Dadurch werden in den Klassen die Property, Getter und Setter ergänzt. Darüber hinaus auch ein passendes privates Feld und Standardcode im Getter und Setter.

3) Die Methoden im Implementationsteil werden analog zur Reihenfolge in den Klassendeklarationen sortiert.


Mein Leidensdruck ist dabei extrem hoch, da bei jedem neuen Property in den Interfaces dieser ganze Mist immer wieder genau gleich in allen benutzenden Klassen durchgeführt werden muss.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 7     123 45     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz