Sign in Join
Wiki copytemporary

Codetools/de: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-## Contents
2-
3- * 1 Was sind die CodeTools
4- * 2 Verwendung der CodeTools ohne die IDE (gut für Testzwecke)
5- * 3 Verwendung der CodeTools in der IDE mit dem IDEIntf
6- * 4 Codetools-Regeln für FPC-Quelltexte
7- * 4.1 Gebrauch von testfpcsrcunitrules
8- * 4.2 Beispiel für testfpcsrcunitrules
9- * 4.3 Doppelte Quelltextdateien
10- * 5 Wie die CodeTools Quelltexte untersuchen, abhängig von einem Kompiler
11- * 6 Clean Position und Kursorposition
12- * 7 Einfügen, Löschen und Ersetzen - der TSourceChangeCache
13- * 7.1 Verwendung
14- * 7.2 BeginUpdate/EndUpdate
15- * 7.3 Speichern Sie die Änderungen auf Disk
16- * 8 Links
17-
181# Was sind die CodeTools
192
20-Die CodeTools sind ein Lazarus-Package mit Werkzeugen zum Parsen, Untersuchen, Bearbeiten und Refaktorieren von Pascal-Quelltexten. Die CodeTools sind ein Modul für sich und unter der GPL lizensiert. Zahlreiche Beispiele, wie Sie die CodeTools in Ihren eigenen Programmen einsetzen können, finden Sie unter 'components/codetools/examples'.
3+Die CodeTools sind ein Lazarus-Package mit Werkzeugen zum Parsen, Untersuchen, Bearbeiten und Refaktorieren von Pascal-Quelltexten. Die CodeTools sind ein Modul für sich und unter der GPL lizensiert. Zahlreiche Beispiele, wie Sie die CodeTools in Ihren eigenen Programmen einsetzen können, finden Sie unter 'components/codetools/examples'.
214
22-svn:
5+svn:
236
24- * Lazarus: <http://svn.freepascal.org/svn/lazarus/trunk>
25- * Nur CodeTools: <http://svn.freepascal.org/svn/lazarus/trunk/components/codetools>
7+- Lazarus: <http://svn.freepascal.org/svn/lazarus/trunk>
8+- Nur CodeTools: <http://svn.freepascal.org/svn/lazarus/trunk/components/codetools>
269
2710# Verwendung der CodeTools ohne die IDE (gut für Testzwecke)
2811
29-Sie können die CodeTools ohne die IDE verwenden. Dies kann zum Testen eines neuen Werkzeugs genutzt werden. Ein einfaches Beispiel ist
30-```
31-<lazarusdir>/components/codetools/examples/methodjumping.lpi
32-```
12+Sie können die CodeTools ohne die IDE verwenden. Dies kann zum Testen eines neuen Werkzeugs genutzt werden. Ein einfaches Beispiel ist
3313
34-Um die _find declaration_ zu testen, müssen die CodeTools die Quellen analysieren, besonders die RTL- und FCL-Quellen. Die Beispiele benutzen folgende Umgebungsvariablen:
14+` <lazarusdir>/components/codetools/examples/methodjumping.lpi`
3515
36- * FPCDIR: der Pfad zu den FPC-Quelltexten, die Vorgabe ist _~/freepascal/fpc_.
37- * PP: der Pfad zum ausführbaren Kompiler (/usr/bin/fpc oder /usr/bin/ppc386 oder C:\lazarus\ppc386.exe). Die CodeTools müssen den Kompiler nach den Einstellungen fragen. Als Vorgabe wird mittels der Variablen 'PATH' nach 'fpc' gesucht.
38- * FPCTARGETOS: weist die CodeTools an, nach einem weiteren Betriebssystem zu suchen ("cross compiling"). Zum Beispiel: linux, freebsd, darwin, win32, win64, wince
39- * FPCTARGETCPU: sucht nach einer anderen CPU. Zum Beispiel: i386, powerpc, x86_64, arm, sparc
40- * LAZARUSDIR: der Pfad zu den Lazarus-Quelltexten. Wird nur benötigt, wenn Sie diese untersuchen wollen.
16+Um die *find declaration* zu testen, müssen die CodeTools die Quellen analysieren, besonders die RTL- und FCL-Quellen. Die Beispiele benutzen folgende Umgebungsvariablen:
4117
42-FPC ist ein sehr komplexes Projekt mit vielen Suchpfaden, Include-Dateien und Makros. Die CodeTools müssen alle diese Pfade und Makros kennen, um diesen Dschungel zu analysieren. Um dies alles einfach einzurichten, enthalten die CodeTools vordefinierte Schablonen für FPC-, Lazarus-, Delphi- und Kylix-Quellverzeichnisse. Betrachten Sie für ein _find declaration_ folgendes Beispiel
43-```
44-<lazarusdir>/components/codetools/examples/finddeclaration.lpi
45-```
18+- FPCDIR: der Pfad zu den FPC-Quelltexten, die Vorgabe ist *~/freepascal/fpc*.
19+- PP: der Pfad zum ausführbaren Kompiler (/usr/bin/fpc oder /usr/bin/ppc386 oder C:\lazarus\ppc386.exe). Die CodeTools müssen den Kompiler nach den Einstellungen fragen. Als Vorgabe wird mittels der Variablen 'PATH' nach 'fpc' gesucht.
20+- FPCTARGETOS: weist die CodeTools an, nach einem weiteren Betriebssystem zu suchen ("cross compiling"). Zum Beispiel: linux, freebsd, darwin, win32, win64, wince
21+- FPCTARGETCPU: sucht nach einer anderen CPU. Zum Beispiel: i386, powerpc, x86_64, arm, sparc
22+- LAZARUSDIR: der Pfad zu den Lazarus-Quelltexten. Wird nur benötigt, wenn Sie diese untersuchen wollen.
4623
47-Weil die FPC-Quellen mehrere Versionen einiger Units enthalten und die FPC-Quellen oft geändert werden, verwenden die CodeTools keine starre Pfadtabelle. Stattdessen scannen sie zuerst die gesamte FPC Verzeichnisstruktur und versuchen mittels einiger Regeln herauszufinden, welche Quelle die richtige ist für das gegenwärtige ZielOS und ZielCPU. Dieser Scan kann eine Weile dauern. Alle Beipiele speichern das Ergebnis in **codetools.config** , damit diese Suche beim nächsten Start übersprungen wird.
24+FPC ist ein sehr komplexes Projekt mit vielen Suchpfaden, Include-Dateien und Makros. Die CodeTools müssen alle diese Pfade und Makros kennen, um diesen Dschungel zu analysieren. Um dies alles einfach einzurichten, enthalten die CodeTools vordefinierte Schablonen für FPC-, Lazarus-, Delphi- und Kylix-Quellverzeichnisse. Betrachten Sie für ein *find declaration* folgendes Beispiel
4825
49-Wann immer die FPC-Quellen verschoben wurden oder eine Unit umbenannt wurde, löschen Sie einfach die Datei **codetools.config**. Die Lazarus-IDE hat ihre eigene Konfigurationsdatei und erledigt den Rescan, wann immer das Compiler executable geändert wurde oder der Benutzer dies erzwingt mit 'Einstellungen > FPC-Quelltextverzeichnis neu einlesen'.
26+` <lazarusdir>/components/codetools/examples/finddeclaration.lpi`
5027
28+Weil die FPC-Quellen mehrere Versionen einiger Units enthalten und die FPC-Quellen oft geändert werden, verwenden die CodeTools keine starre Pfadtabelle. Stattdessen scannen sie zuerst die gesamte FPC Verzeichnisstruktur und versuchen mittels einiger Regeln herauszufinden, welche Quelle die richtige ist für das gegenwärtige ZielOS und ZielCPU. Dieser Scan kann eine Weile dauern. Alle Beipiele speichern das Ergebnis in **codetools.config**, damit diese Suche beim nächsten Start übersprungen wird.
29+
30+Wann immer die FPC-Quellen verschoben wurden oder eine Unit umbenannt wurde, löschen Sie einfach die Datei **codetools.config**. Die Lazarus-IDE hat ihre eigene Konfigurationsdatei und erledigt den Rescan, wann immer das Compiler executable geändert wurde oder der Benutzer dies erzwingt mit 'Einstellungen \> FPC-Quelltextverzeichnis neu einlesen'.
31+
5132# Verwendung der CodeTools in der IDE mit dem IDEIntf
5233
53-Siehe das <lazarusdir>/examples/idequickfix/quickfixexample.lpk Package. Es demonstriert:
34+Siehe das \<lazarusdir\>/examples/idequickfix/quickfixexample.lpk Package. Es demonstriert:
5435
55- * Wie man ein IDE-Package schreibt. Wenn Sie es installieren, wird es ein Quick-Fix-Element registrieren.
56- * Wie man ein Quick-Fix-Element schreibt für die Compilermeldung 'Parameter "Sender" not used'
57- * Wie man die CodeTools verwendet, um
58- * eine Unit zu analysieren
59- * Dateiname, Zeile, Spalte in eine CodeTools Quelltextposition umzuwandeln
60- * ein CodeTools-Element an der Cursorposition zu finden
61- * ein 'procedure'-Element und das 'begin..end'-Element zu finden
62- * für eine Anweisung eine günstige Einfügeposition am Anfang eines 'begin..end'-Blocks zu ermitteln
63- * die Einrückung einer Zeile zu erhalten, damit sich die neue Zeile in die Prozedur einfügt
64- * Code einzufügen mit den CodeTools
36+- Wie man ein IDE-Package schreibt. Wenn Sie es installieren, wird es ein Quick-Fix-Element registrieren.
37+- Wie man ein Quick-Fix-Element schreibt für die Compilermeldung 'Parameter "Sender" not used'
38+- Wie man die CodeTools verwendet, um
39+ - eine Unit zu analysieren
40+ - Dateiname, Zeile, Spalte in eine CodeTools Quelltextposition umzuwandeln
41+ - ein CodeTools-Element an der Cursorposition zu finden
42+ - ein 'procedure'-Element und das 'begin..end'-Element zu finden
43+ - für eine Anweisung eine günstige Einfügeposition am Anfang eines 'begin..end'-Blocks zu ermitteln
44+ - die Einrückung einer Zeile zu erhalten, damit sich die neue Zeile in die Prozedur einfügt
45+ - Code einzufügen mit den CodeTools
6546
6647# Codetools-Regeln für FPC-Quelltexte
6748
68-Wenn die CodeTools die Quelltexte nach einer FPC ppu-Datei durchsuchen, verwenden sie einen Satz von Regeln. Sie können Ihre eigenen Regeln Schreiben, aber normalerweise werden Sie die Standardregeln benutzen, die in der der Includedatei 'components/codetools/fpcsrcrules.inc' festgelegt sind. Sie können die Regeln testen mit dem Befehlszeilenwerkzeug: components/codetools/examples/testfpcsrcunitrules.lpi.
49+Wenn die CodeTools die Quelltexte nach einer FPC ppu-Datei durchsuchen, verwenden sie einen Satz von Regeln. Sie können Ihre eigenen Regeln Schreiben, aber normalerweise werden Sie die Standardregeln benutzen, die in der der Includedatei 'components/codetools/fpcsrcrules.inc' festgelegt sind. Sie können die Regeln testen mit dem Befehlszeilenwerkzeug: components/codetools/examples/testfpcsrcunitrules.lpi.
6950
7051## Gebrauch von testfpcsrcunitrules
71-```
72-Gebrauch: lazarus/components/codetools/examples/testfpcsrcunitrules -h
73-
52+
53+ Gebrauch: lazarus/components/codetools/examples/testfpcsrcunitrules -h
54+
7455 -c <compiler file name>, --compiler=<compiler file name>
7556 Vorgabe ist es, die Umgebungsvariable PP zu benutzen.
7657 Wenn nicht angegeben, suche nach fpc
77-
58+
7859 -T <target OS>, --targetos=<target OS>
7960 Vorgabe ist es, die Umgebungsvariable FPCTARGET zu benutzen.
8061 Wenn nicht angegeben, nimm die Vorgabe des Kompilers.
81-
62+
8263 -P <target CPU>, --targetcpu=<target CPU>
8364 Vorgabe ist es, die Umgebungsvariable FPCTARGETCPU zu benutzen.
8465 Wenn nicht angegeben, nimm die Vorgabe des Kompilers.
85-
66+
8667 -F <FPC source directory>, --fpcsrcdir=<FPC source directory>
8768 Vorgabe ist es, die Umgebungsvariable FPCDIR zu benutzen.
8869 Es gibt keine andere Vorgabe.
89-
70+
9071 -u <unit name>, --checkunit=<unit name>
9172 Schreibe einen detailierten Bericht über diese Unit.
92-```
9373
9474## Beispiel für testfpcsrcunitrules
9575
96-Öffnen Sie die Datei 'testfpcsrcunitrules.lpi' in der IDE und kompilieren Sie sie. Starten Sie dann das Werkzeug in einer Befehlszeile/Konsole:
97-```
98-./testfpcsrcunitrules -F ~/fpc/sources/2.5.1/fpc/
99-```
76+Öffnen Sie die Datei 'testfpcsrcunitrules.lpi' in der IDE und kompilieren Sie sie. Starten Sie dann das Werkzeug in einer Befehlszeile/Konsole:
10077
101-Dadurch erfahren Sie, welcher Kompiler benutzt wird, welcher Kompiler ausgeführt wird, welche Konfigurationsdateinen getestet und analysiert wurden, Sie werden gewarnt über doppelte Units im FPC-Suchpfad und doppelte Quelltextdateien für die selbe Unit.
78+`./testfpcsrcunitrules -F ~/fpc/sources/2.5.1/fpc/`
10279
80+Dadurch erfahren Sie, welcher Kompiler benutzt wird, welcher Kompiler ausgeführt wird, welche Konfigurationsdateinen getestet und analysiert wurden, Sie werden gewarnt über doppelte Units im FPC-Suchpfad und doppelte Quelltextdateien für die selbe Unit.
81+
10382## Doppelte Quelltextdateien
10483
105-Angenommen, Sie finden heraus, dass die CodeTools für das Ziel 'wince/arm' den falschen Quelltext der Unit _mmsystem_ öffnen. Starten Sie das Werkzeug mit dem Parameter '-u':
84+Angenommen, Sie finden heraus, dass die CodeTools für das Ziel 'wince/arm' den falschen Quelltext der Unit *mmsystem* öffnen. Starten Sie das Werkzeug mit dem Parameter '-u':
10685
107-./testfpcsrcunitrules -F ~/fpc/2.5.1/fpc/ -T wince -P arm -u mmsystem
86+./testfpcsrcunitrules -F ~/fpc/2.5.1/fpc/ -T wince -P arm -u mmsystem
10887
109-Dadurch erhalten Sie einen detaillierten Bericht darüber, wo diese Unit gefunden wurde und welches Score jede Quelltextdatei erzielt hat. Zum Beispiel:
110-```
111-Unit report for mmsystem
112- WARNING: mmsystem is not in PPU search path
113- GatherUnitsInFPCSources UnitName=mmsystem File=packages/winunits-base/src/mmsystem.pp Score=11
114- GatherUnitsInFPCSources UnitName=mmsystem File=packages/winceunits/src/mmsystem.pp Score=11 => duplicate
115-```
88+Dadurch erhalten Sie einen detaillierten Bericht darüber, wo diese Unit gefunden wurde und welches Score jede Quelltextdatei erzielt hat. Zum Beispiel:
11689
117-Dies bedeutet, dass es zwei Quelltextdateien mit dem selben Score gibt, sodass die CodeTools die erste genommen haben. Die letzte im Verzeichnis 'winceunits' ist für das Ziel 'wince' und die erste ist für 'win32' und 'win64'.
90+`Unit report for mmsystem`\
91+`  WARNING: mmsystem is not in PPU search path`\
92+`GatherUnitsInFPCSources UnitName=mmsystem File=packages/winunits-base/src/mmsystem.pp Score=11`\
93+`GatherUnitsInFPCSources UnitName=mmsystem File=packages/winceunits/src/mmsystem.pp Score=11 => duplicate`
11894
119-Öffnen Sie jetzt die Regeldatei 'fpcsrcrules.inc'.
95+Dies bedeutet, dass es zwei Quelltextdateien mit dem selben Score gibt, sodass die CodeTools die erste genommen haben. Die letzte im Verzeichnis 'winceunits' ist für das Ziel 'wince' und die erste ist für 'win32' und 'win64'.
12096
121-Regeln arbeiten so:
122-```
97+Öffnen Sie jetzt die Regeldatei 'fpcsrcrules.inc'.
98+
99+Regeln arbeiten so:
100+
101+``` pascal
123102Score:=10;
124- Targets:='wince';
125- Add('packages/winceunits');
103+Targets:='wince';
104+Add('packages/winceunits');
126105```
127106
128-Das **Add** fügt eine Regel hinzu für alle Dateien, die mit 'packages/winceunits' beginnen. Zum Score all dieser Dateien wird 10 addiert. **Targets** ist eine durch Kommas getrennte Liste von Zielbetriebssystemen und/oder Zielprozessoren. Beispielsweise: Targets='wince,linux,i386' bedeutet: wende diese Regel auf das ZielOS 'wince' oder 'linux' und auf die ZielCPU i386 an.
107+Das **Add** fügt eine Regel hinzu für alle Dateien, die mit 'packages/winceunits' beginnen. Zum Score all dieser Dateien wird 10 addiert. **Targets** ist eine durch Kommas getrennte Liste von Zielbetriebssystemen und/oder Zielprozessoren. Beispielsweise: Targets='wince,linux,i386' bedeutet: wende diese Regel auf das ZielOS 'wince' oder 'linux' und auf die ZielCPU i386 an.
129108
130109# Wie die CodeTools Quelltexte untersuchen, abhängig von einem Kompiler
131110
132-Ein Kompiler ist dazu optimiert den Code linear zu durchlaufen und die benötigten Units und Includedateien dann zu laden, wenn er einen uses-Abschnitt oder eine Direktive findet. Die CodeTools sind dazu optimiert, nur Teile des Codes zu untersuchen. Beispielsweise braucht der Sprung von einer Methodendeklaration zum Methodenrumpf nur die Unit und ihre Includedateien. Wenn die CodeTools eine Deklaration suchen, dann suchen sie rückwärts. Das bedeutet, sie starten die Suche in den lokalen Variablen und dann oberhalb in der Implementation. Wenn sie einen uses-Abschnitt vorfinden, suchen sie den Bezeichner im Abschnitt 'interface' der Units. Wird der Bezeichner gefunden, halten sie an. Das Ergebnis und einige Zwischenschritte werden gecached. Weil oftmals nur einige interface-Abschnitte durchsucht werden müssen, wird ein einzelner Bezeichner rasch gefunden.
111+Ein Kompiler ist dazu optimiert den Code linear zu durchlaufen und die benötigten Units und Includedateien dann zu laden, wenn er einen uses-Abschnitt oder eine Direktive findet. Die CodeTools sind dazu optimiert, nur Teile des Codes zu untersuchen. Beispielsweise braucht der Sprung von einer Methodendeklaration zum Methodenrumpf nur die Unit und ihre Includedateien. Wenn die CodeTools eine Deklaration suchen, dann suchen sie rückwärts. Das bedeutet, sie starten die Suche in den lokalen Variablen und dann oberhalb in der Implementation. Wenn sie einen uses-Abschnitt vorfinden, suchen sie den Bezeichner im Abschnitt 'interface' der Units. Wird der Bezeichner gefunden, halten sie an. Das Ergebnis und einige Zwischenschritte werden gecached. Weil oftmals nur einige interface-Abschnitte durchsucht werden müssen, wird ein einzelner Bezeichner rasch gefunden.
133112
134-Die CodeTools durchsuchen einen Quelltext nicht in einem Durchgang wie ein Kompiler, sondern in mehreren Durchgängen, abhängig von den Erfordernissen der aktuellen Funktion:
113+Die CodeTools durchsuchen einen Quelltext nicht in einem Durchgang wie ein Kompiler, sondern in mehreren Durchgängen, abhängig von den Erfordernissen der aktuellen Funktion:
135114
136- * Zuerst wird ein Quelltext in einen TCodeBuffer geladen. Die IDE benutzt diesen Schritt, um die Kodierung in UTF8 zu ändern. Die Dateien werden im Speicher gehalten und nur nachgeladen, wenn sich das Änderungsdatum ändert oder eine Datei manuell umgeändert wird. Es gibt einige Tools und Funktionen die direkt mit dem Puffer arbeiten.
137- * Die nächste Ebene ist das Untersuchen einer Unit oder Includedatei. Eine Unit muss vom Anfang an durchlaufen werden, deshalb versuchen die CodeTools die Hauptdatei herauszufinden, die erste Datei einer Unit. Dabei suchen sie in der ersten Zeile nach einer Direktive, wie {%MainUnit ../lclintf.pp}. Falls diese nicht existiert, wird der 'includelink cache' durchsucht. Die IDE speichert diesen Cache auf dem Laufwerk, so lernt die IDE mit der Zeit dazu.
138- * Nachdem die Hauptdatei gefunden wurde, scannt TLinkScanner den Quelltext. Er verarbeitet Kompilerdirektiven, wie Include-Direktiven und 'if-else'-Direktiven. Dem Scanner kann ein Bereich übergeben werden, beispielsweise um nur das Interface einer Unit zu durchsuchen. Der Scanner erzeugt den **clean source**. Der 'clean source' besteht aus allen Includedateien und befreit von sämtlichen übersprungenen Codestellen aus den 'else'-Teilen. Er erzeugt auch eine Liste von **links** , die den 'clean source' und die realen Quelltextdatein verbinden. Der 'clean source' ist jetzt Pascal. Beachten Sie: es gibt auch Tools, um eine einzelne Quelle nach allen Direktiven zu durchsuchen und einen Direktivenbaum zu erstellen.
139- * Nach dem Erzeugen des 'clean source' untersucht ein TCodeTool diesen und erstellt einen Baum von 'TCodeTreeNode'-Elementen. Auch hier ist eine Bereichsangabe möglich. Dieser Parser überspringt einige Teile, zum Beispiel 'class members', 'begin..end'-Blocks und Parameterlisten. Viele Tools brauchen diese nicht. Diese Unterknoten werden nur bei Bedarf erzeugt. Ein TCodeTreeNode hat einen Bereich StartPos..EndPos, welche 'clean positions' sind, also Positionen im 'clean source'. Es gibt nur Knoten für die wichtigen Teile. Knoten für jedes Detail zu erstellen würde mehr Speicher benötigen als der Quelltext selbst und ist auch selten erforderlich. Zahlreiche Funktionen sind dazu da, die Details herauszufinden. Ob beispielsweise eine Funktion der Aufrufskonvention 'cdecl' entspricht.
140- * Wird ein Bezeichner gesucht, dann speichert die Suche die gefundenen Basistypen und erzeugt Caches für alle Bezeichner aus dem Interface-Abschnitt.
115+- Zuerst wird ein Quelltext in einen TCodeBuffer geladen. Die IDE benutzt diesen Schritt, um die Kodierung in UTF8 zu ändern. Die Dateien werden im Speicher gehalten und nur nachgeladen, wenn sich das Änderungsdatum ändert oder eine Datei manuell umgeändert wird. Es gibt einige Tools und Funktionen die direkt mit dem Puffer arbeiten.
116+- Die nächste Ebene ist das Untersuchen einer Unit oder Includedatei. Eine Unit muss vom Anfang an durchlaufen werden, deshalb versuchen die CodeTools die Hauptdatei herauszufinden, die erste Datei einer Unit. Dabei suchen sie in der ersten Zeile nach einer Direktive, wie {%MainUnit ../lclintf.pp}. Falls diese nicht existiert, wird der 'includelink cache' durchsucht. Die IDE speichert diesen Cache auf dem Laufwerk, so lernt die IDE mit der Zeit dazu.
117+- Nachdem die Hauptdatei gefunden wurde, scannt TLinkScanner den Quelltext. Er verarbeitet Kompilerdirektiven, wie Include-Direktiven und 'if-else'-Direktiven. Dem Scanner kann ein Bereich übergeben werden, beispielsweise um nur das Interface einer Unit zu durchsuchen. Der Scanner erzeugt den **clean source**. Der 'clean source' besteht aus allen Includedateien und befreit von sämtlichen übersprungenen Codestellen aus den 'else'-Teilen. Er erzeugt auch eine Liste von **links**, die den 'clean source' und die realen Quelltextdatein verbinden. Der 'clean source' ist jetzt Pascal. Beachten Sie: es gibt auch Tools, um eine einzelne Quelle nach allen Direktiven zu durchsuchen und einen Direktivenbaum zu erstellen.
118+- Nach dem Erzeugen des 'clean source' untersucht ein TCodeTool diesen und erstellt einen Baum von 'TCodeTreeNode'-Elementen. Auch hier ist eine Bereichsangabe möglich. Dieser Parser überspringt einige Teile, zum Beispiel 'class members', 'begin..end'-Blocks und Parameterlisten. Viele Tools brauchen diese nicht. Diese Unterknoten werden nur bei Bedarf erzeugt. Ein TCodeTreeNode hat einen Bereich StartPos..EndPos, welche 'clean positions' sind, also Positionen im 'clean source'. Es gibt nur Knoten für die wichtigen Teile. Knoten für jedes Detail zu erstellen würde mehr Speicher benötigen als der Quelltext selbst und ist auch selten erforderlich. Zahlreiche Funktionen sind dazu da, die Details herauszufinden. Ob beispielsweise eine Funktion der Aufrufskonvention 'cdecl' entspricht.
119+- Wird ein Bezeichner gesucht, dann speichert die Suche die gefundenen Basistypen und erzeugt Caches für alle Bezeichner aus dem Interface-Abschnitt.
141120
142-Jede Ebene hat ihre eigenen Caches, die vor dem Aufruf einer Funktion geprüft und aktualisiert werden müssen. Viele High-level-Funktionen, auf die mittels 'CodeToolBoss' zugegriffen werden kann, machen das automatisch. Für andere liegt die Verantwortung beim aufrufenden Prozess.
121+Jede Ebene hat ihre eigenen Caches, die vor dem Aufruf einer Funktion geprüft und aktualisiert werden müssen. Viele High-level-Funktionen, auf die mittels 'CodeToolBoss' zugegriffen werden kann, machen das automatisch. Für andere liegt die Verantwortung beim aufrufenden Prozess.
143122
144-Ein Beispiel dafür:
123+Ein Beispiel dafür:
145124
146-unti1.pas:
147-```
125+unti1.pas:
126+
127+``` pascal
148128unit Unit1;
149- {$I settings.inc}
150- interface
151- uses
152- {$IFDEF Flag}
153- unix,
154- {$ELSE}
155- windows,
156- {$ENDIF}
157- Classes;
129+{$I settings.inc}
130+interface
131+uses
132+ {$IFDEF Flag}
133+ unix,
134+ {$ELSE}
135+ windows,
136+ {$ENDIF}
137+ Classes;
158138```
159139
160-settings.inc:
161-```
140+settings.inc:
141+
142+``` pascal
162143{%MainUnit unit1.pas}
163- {$DEFINE Flag}
144+{$DEFINE Flag}
164145```
165146
166-clean source:
167-```
147+clean source:
148+
149+``` pascal
168150unit Unit1;
169- {$I settings.inc}{%MainUnit unit1.pas}
170- {$DEFINE Flag}
171- interface
172- uses
173- {$IFDEF Flag}
174- unix,
175- {$ELSE}{$ENDIF}
176- Classes;
151+{$I settings.inc}{%MainUnit unit1.pas}
152+{$DEFINE Flag}
153+interface
154+uses
155+ {$IFDEF Flag}
156+ unix,
157+ {$ELSE}{$ENDIF}
158+ Classes;
177159```
178160
179-
180-Tipp: Um eine Unit einfach zu durchlaufen und die Knoten zu erstellen, verwenden Sie **CodeToolBoss.Explore**.
161+Tipp: Um eine Unit einfach zu durchlaufen und die Knoten zu erstellen, verwenden Sie **CodeToolBoss.Explore**.
181162
182163# Clean Position und Kursorposition
183164
184-Es gibt verschiedene Methoden, um in den CodeTools eine Position zu definieren.
165+Es gibt verschiedene Methoden, um in den CodeTools eine Position zu definieren.
185166
186-Die absolute Position bezieht sich auf den Quelltext als Zeichenkette und beginnt bei 1. Beispielsweise hält ein TCodeBuffer den Dateiinhalt als Zeichenkette in der Eigenschaft 'Source'. Die Positionen der Einfügemarke oder des Kursors sind als X,Y gegeben, wobei Y die Zeilennummer ist (bei 1 beginnend) und X die Spaltennummer (bei 1 beginnend). Ein TCodeBuffer stellt zum Umwandeln die Funktionen **LineColToPosition'_und_** _AbsoluteToLineCol_ zur Verfügung. Wenn Sie mit mehreren Quelltextdateinen arbeiten, wie einer Unit, die aus verschiedenen Includedateien bestehen kann, dann bezieht sich 'Clean Position' auf die absolute Position im bereinigten Code **Src**. Src ist eine Zeichenkette und Clean Positions beginnt bei 1. Die Kursorpositionen werden angegeben als TCodeXYPosition (Code,X,Y). Ein TCodeTool stellt zum Umwandeln die Funktionen **CaretToCleanPos** , **CleanPosToCaret** zur Verfügung.
167+Die absolute Position bezieht sich auf den Quelltext als Zeichenkette und beginnt bei 1. Beispielsweise hält ein TCodeBuffer den Dateiinhalt als Zeichenkette in der Eigenschaft 'Source'. Die Positionen der Einfügemarke oder des Kursors sind als X,Y gegeben, wobei Y die Zeilennummer ist (bei 1 beginnend) und X die Spaltennummer (bei 1 beginnend). Ein TCodeBuffer stellt zum Umwandeln die Funktionen **LineColToPosition** und **AbsoluteToLineCol'' zur Verfügung. Wenn Sie mit mehreren Quelltextdateinen arbeiten, wie einer Unit, die aus verschiedenen Includedateien bestehen kann, dann bezieht sich 'Clean Position' auf die absolute Position im bereinigten Code**Src**. Src ist eine Zeichenkette und Clean Positions beginnt bei 1. Die Kursorpositionen werden angegeben als TCodeXYPosition (Code,X,Y). Ein TCodeTool stellt zum Umwandeln die Funktionen**CaretToCleanPos**,**CleanPosToCaret''' zur Verfügung.
187168
188169# Einfügen, Löschen und Ersetzen - der TSourceChangeCache
189170
190-Wenn Sie Änderungen am Quelltext einer Unit (oder ihrer Includedateien) vornehmen, sollten Sie dazu 'CodetoolBoss.SourceChangeCache' benutzen, weil:
171+Wenn Sie Änderungen am Quelltext einer Unit (oder ihrer Includedateien) vornehmen, sollten Sie dazu 'CodetoolBoss.SourceChangeCache' benutzen, weil:
191172
192- * Einfache Anwendung. Verbinden, ersetzen, ersetzen, ... anwenden. Siehe unten.
193- * Sie benutzen 'cleanpos' wie durch den Knotenbaum gegeben ODER Sie benutzen die direkten Positionen in einer Datei.
194- * Sie können 'Replace' zum Einfügen und Löschen benutzen. Dies löst automatisch Ereignisse aus, wodurch verbundene Editoren über Veränderungen benachrichtigt werden.
195- * Es können automatisch benötigte Leerzeichen eingefügt werden, ebenso Zeilenendezeichen oder Leerzeilen vor doer nach jedem Replace. Zum Beispiel definieren Sie, dass jeweils eine Leerzeile voran gehen soll. Der SourceChangeCache prüft, was eingefügt werden soll, wie viel Platz bereits dort ist und wird den notwendigen Platz einfügen.
196- * Er überprüft, ob der Bereich für Ersetzen/Löschen beschreibbar ist.
197- * Sie können mehrfache Ersetzungen vornehmen und Sie steuern, wann diese angewendet werden. Bedenken Sie dabei, dass das Einfügen von Code bedeutet, dass der untersuchte Baum ungültig wird und neu erstellt werden muss.
198- * Mehrfache Ersetzungen werden auf Überschneidungen geprüft. Zum Beispiel erhalten Sie beim Einfügen in der Mitte eines gelöschten Codes eine Fehlermeldung.
199- * Mehrfache Ersetzungen an der selben Stelle werden reihenweise abgearbeitet (nach dem FIFO-Prinzip).
200- * Sie können verschiedene Funktionen zum Bearbeiten von Code zu einer größeren Funktion kombinieren. Siehe unten.
173+- Einfache Anwendung. Verbinden, ersetzen, ersetzen, ... anwenden. Siehe unten.
174+- Sie benutzen 'cleanpos' wie durch den Knotenbaum gegeben ODER Sie benutzen die direkten Positionen in einer Datei.
175+- Sie können 'Replace' zum Einfügen und Löschen benutzen. Dies löst automatisch Ereignisse aus, wodurch verbundene Editoren über Veränderungen benachrichtigt werden.
176+- Es können automatisch benötigte Leerzeichen eingefügt werden, ebenso Zeilenendezeichen oder Leerzeilen vor doer nach jedem Replace. Zum Beispiel definieren Sie, dass jeweils eine Leerzeile voran gehen soll. Der SourceChangeCache prüft, was eingefügt werden soll, wie viel Platz bereits dort ist und wird den notwendigen Platz einfügen.
177+- Er überprüft, ob der Bereich für Ersetzen/Löschen beschreibbar ist.
178+- Sie können mehrfache Ersetzungen vornehmen und Sie steuern, wann diese angewendet werden. Bedenken Sie dabei, dass das Einfügen von Code bedeutet, dass der untersuchte Baum ungültig wird und neu erstellt werden muss.
179+- Mehrfache Ersetzungen werden auf Überschneidungen geprüft. Zum Beispiel erhalten Sie beim Einfügen in der Mitte eines gelöschten Codes eine Fehlermeldung.
180+- Mehrfache Ersetzungen an der selben Stelle werden reihenweise abgearbeitet (nach dem FIFO-Prinzip).
181+- Sie können verschiedene Funktionen zum Bearbeiten von Code zu einer größeren Funktion kombinieren. Siehe unten.
201182
202183## Verwendung
203184
204-Der SourceChangeCache arbeitet mit einer Unit, deshalb müssen Sie ein TCodeTool nehmen und eine Unit/Includedatei damit scannen. Zum Beispiel:
205-```
206-// Schritt 1: lade die Datei und untersuche sie
207- Code:=CodeToolBoss.LoadFile(Filename,false,false);
208- if Code=nil then
209- raise Exception.Create('loading failed '+Filename);
210- if not CodeToolBoss.Explore(Code,Tool,false) then
211- ...;// Fehler beim Untersuchen ...
212-
213- // Schritt 2: verbinde mit dem SourceChangeCache
214- CodeToolBoss.SourceChangeCache.MainScanner:=Tool.Scanner;
215-
216- // Schritt 3: nimm Replace zum Einfügen und/oder Löschen von Code.
217- // Die beiden ersten Parameter sind die benötigten Leerzeichen vor und hinter der Einfügestelle.
218- // FromPos, ToPos legen den gelöschten/ersetzten Bereich in CleanPos-Positionen fest.
219- // NewCode ist die Zeichenkette des neuen Codes. Verwenden Sie '' zum Löschen.
220- if not CodeToolBoss.SourceChangeCache.Replace(gtNone,gtNone,FromPos,ToPos,NewCode) then
221- exit; // z.B. Quelltext ist nicht beschreibbar oder ein vorangegangenes Ersetzen hat diese Stelle gelöscht
222- ...einige weitere Ersetzungen...
223-
224- // Schritt 4: wende die Änderungen an
225- if not CodeToolBoss.SourceChangeCache.Apply then
226- exit; // Anwendung wurde abgebrochen
185+Der SourceChangeCache arbeitet mit einer Unit, deshalb müssen Sie ein TCodeTool nehmen und eine Unit/Includedatei damit scannen. Zum Beispiel:
186+
187+``` pascal
188+ // Schritt 1: lade die Datei und untersuche sie
189+ Code:=CodeToolBoss.LoadFile(Filename,false,false);
190+ if Code=nil then
191+ raise Exception.Create('loading failed '+Filename);
192+ if not CodeToolBoss.Explore(Code,Tool,false) then
193+ ...;// Fehler beim Untersuchen ...
194+
195+ // Schritt 2: verbinde mit dem SourceChangeCache
196+ CodeToolBoss.SourceChangeCache.MainScanner:=Tool.Scanner;
197+
198+ // Schritt 3: nimm Replace zum Einfügen und/oder Löschen von Code.
199+ // Die beiden ersten Parameter sind die benötigten Leerzeichen vor und hinter der Einfügestelle.
200+ // FromPos, ToPos legen den gelöschten/ersetzten Bereich in CleanPos-Positionen fest.
201+ // NewCode ist die Zeichenkette des neuen Codes. Verwenden Sie '' zum Löschen.
202+ if not CodeToolBoss.SourceChangeCache.Replace(gtNone,gtNone,FromPos,ToPos,NewCode) then
203+ exit; // z.B. Quelltext ist nicht beschreibbar oder ein vorangegangenes Ersetzen hat diese Stelle gelöscht
204+ ...einige weitere Ersetzungen...
205+
206+ // Schritt 4: wende die Änderungen an
207+ if not CodeToolBoss.SourceChangeCache.Apply then
208+ exit; // Anwendung wurde abgebrochen
227209```
228210
229211## BeginUpdate/EndUpdate
230212
231-BeginUpdate/EndUpdate verzögert die Anwendung. Dies ist nützlich, wenn Sie verschiedene Code ändernde Funktionen kombinieren. Zum Beispiel:
213+BeginUpdate/EndUpdate verzögert die Anwendung. Dies ist nützlich, wenn Sie verschiedene Code ändernde Funktionen kombinieren. Zum Beispiel:
232214
233-Sie wollen die Unit scannen, fügen eine Unit in der uses-Klausel des Interface-Bereichs hinzu und entfernen die Unit aus der uses-Klausel des Implementation-Bereichs. Die zwei Funktionen 'AddUnitToMainUsesSection' und 'RemoveUnitFromUsesSection' benutzen 'Apply', ändern den Quelltext, sodass die zweite Funktion die Unit ein zweites Mal scannen würde. Weil aber beide Funktionen voneinander unabhängig sind (Sie verändern verschiedene Teile des Quelltextes) können Sie beide miteinander kombinieren und nur einen Scan machen:
234-```
235-// Schritt 1: durchsuche die Unit und verbinde mit SourceChangeCache
236- if not CodeToolBoss.Explore(Code,Tool,false) then
237- ...;// Fehler beim Untersuchen ...
238- CodeToolBoss.SourceChangeCache.MainScanner:=Tool.Scanner;
239-
240- // Schritt 2: verzögere die Anwendung
241- CodeToolBoss.SourceChangeCache.BeginUpdate;
242-
243- // Schritt 3: füge die Unit zum Interface-Bereich hinzu
244- // AddUnitToMainUsesSection würde angewendet und den Code ändern
245- // Wegen BeginUpdate finden die Änderungen noch nicht statt, werden aber in SourceChangeCache gespeichert
246- if not Tool.AddUnitToMainUsesSection('Classes','',CodeToolBoss.SourceChangeCache) then exit;
247-
248- // Schritt 4: entferne die Unit aus dem Implementation-Bereich
249- // Ohne BeginUpdate würde RemoveUnitFromUsesSection die Unit erneut scannen
250- if Tool.FindImplementationUsesSection<>nil then
251- if not Tool.RemoveUnitFromUsesSection(Tool.FindImplementationUsesSection,'Classes',CodeToolBoss.SourceChangeCache) then exit;
252-
253- // Schritt 5: wende alle Änderungen an
254- if not CodeToolBoss.SourceChangeCache.EndUpdate then
255- exit; // Anwendung wurde abgebrochen
215+Sie wollen die Unit scannen, fügen eine Unit in der uses-Klausel des Interface-Bereichs hinzu und entfernen die Unit aus der uses-Klausel des Implementation-Bereichs. Die zwei Funktionen 'AddUnitToMainUsesSection' und 'RemoveUnitFromUsesSection' benutzen 'Apply', ändern den Quelltext, sodass die zweite Funktion die Unit ein zweites Mal scannen würde. Weil aber beide Funktionen voneinander unabhängig sind (Sie verändern verschiedene Teile des Quelltextes) können Sie beide miteinander kombinieren und nur einen Scan machen:
216+
217+``` pascal
218+ // Schritt 1: durchsuche die Unit und verbinde mit SourceChangeCache
219+ if not CodeToolBoss.Explore(Code,Tool,false) then
220+ ...;// Fehler beim Untersuchen ...
221+ CodeToolBoss.SourceChangeCache.MainScanner:=Tool.Scanner;
222+
223+ // Schritt 2: verzögere die Anwendung
224+ CodeToolBoss.SourceChangeCache.BeginUpdate;
225+
226+ // Schritt 3: füge die Unit zum Interface-Bereich hinzu
227+ // AddUnitToMainUsesSection würde angewendet und den Code ändern
228+ // Wegen BeginUpdate finden die Änderungen noch nicht statt, werden aber in SourceChangeCache gespeichert
229+ if not Tool.AddUnitToMainUsesSection('Classes','',CodeToolBoss.SourceChangeCache) then exit;
230+
231+ // Schritt 4: entferne die Unit aus dem Implementation-Bereich
232+ // Ohne BeginUpdate würde RemoveUnitFromUsesSection die Unit erneut scannen
233+ if Tool.FindImplementationUsesSection<>nil then
234+ if not Tool.RemoveUnitFromUsesSection(Tool.FindImplementationUsesSection,'Classes',CodeToolBoss.SourceChangeCache) then exit;
235+
236+ // Schritt 5: wende alle Änderungen an
237+ if not CodeToolBoss.SourceChangeCache.EndUpdate then
238+ exit; // Anwendung wurde abgebrochen
256239```
257240
258-BeginUpdate/EndUpdate arbeiten mit einem Zähler, wenn Sie also BeginUpdate zwei Mal aufrufen, müssen Sie auch EndUpdate zwei Mal aufrufen. Dies bedeutet, dass Sie obiges Beispiel in eine Funktion stellen und mit einer weiteren Funktion kombinieren können.
241+BeginUpdate/EndUpdate arbeiten mit einem Zähler, wenn Sie also BeginUpdate zwei Mal aufrufen, müssen Sie auch EndUpdate zwei Mal aufrufen. Dies bedeutet, dass Sie obiges Beispiel in eine Funktion stellen und mit einer weiteren Funktion kombinieren können.
259242
260243## Speichern Sie die Änderungen auf Disk
261244
262-Die obigen Änderungen werden nur in den Codepuffern gemacht und diese Puffer als 'verändert' markiert. Um die Änderungen auf Disk zu speichern, müssen Sie für jeden veränderten Puffer 'Save' aufrufen.
245+Die obigen Änderungen werden nur in den Codepuffern gemacht und diese Puffer als 'verändert' markiert. Um die Änderungen auf Disk zu speichern, müssen Sie für jeden veränderten Puffer 'Save' aufrufen.
263246
264- * Die Puffer, die mit dem nächsten Apply/EndUpdate geändert werden liegen in 'SourceChangeCache.BuffersToModify' und 'BuffersToModifyCount'.
265- * Die Ereignisse 'SourceChangeCache.OnBeforeApplyChanges/OnAfterApplyChanges' werden von CodeToolBoss benutzt, der sie mit seinen eigenen 'OnBeforeApplyChanges/OnAfterApplyChanges' verbindet. Die Lazarus-IDE setzt diese Ereignisse und öffnet automatisch die geänderten Dateien im Quelltexteditor, dadurch scheinen alle Änderungen in der Undo-Liste von Synedit auf.
247+- Die Puffer, die mit dem nächsten Apply/EndUpdate geändert werden liegen in 'SourceChangeCache.BuffersToModify' und 'BuffersToModifyCount'.
248+- Die Ereignisse 'SourceChangeCache.OnBeforeApplyChanges/OnAfterApplyChanges' werden von CodeToolBoss benutzt, der sie mit seinen eigenen 'OnBeforeApplyChanges/OnAfterApplyChanges' verbindet. Die Lazarus-IDE setzt diese Ereignisse und öffnet automatisch die geänderten Dateien im Quelltexteditor, dadurch scheinen alle Änderungen in der Undo-Liste von Synedit auf.
266249
267250# Links
268251
269- * [[Lazarus IDE Tools/de|Lazarus IDE Tools (deutsch)]] \- Ein Tutorial über die eingebauten Werkzeuge der Standard-IDE.
270- * [[Cody]] \- ein IDE-Package mit fortgeschrittenen CodeTools.
271- * [[Extending the IDE/de|Erweitern der IDE (deutsch)]] \- Wie Sie Ihre eigenen CodeTool-Plugins für die IDE schreiben.
252+- [[Lazarus IDE Tools/de|Lazarus IDE Tools (deutsch)]] - Ein Tutorial über die eingebauten Werkzeuge der Standard-IDE.
253+- [[Cody]] - ein IDE-Package mit fortgeschrittenen CodeTools.
254+- [[Extending the IDE/de|Erweitern der IDE (deutsch)]] - Wie Sie Ihre eigenen CodeTool-Plugins für die IDE schreiben.
272255
273256---
274-*From the Free Pascal wiki, page "Codetools/de", as the Internet Archive kept it on 2023-06-07. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
257+*From the Free Pascal wiki, page "Codetools/de", as it stood on 2020-02-11 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history