AGB  ·  Datenschutz  ·  Impressum  







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

Regionen ersetzen - fertige Funktionen?

Ein Thema von stahli · begonnen am 24. Mär 2011 · letzter Beitrag vom 28. Mär 2011
Antwort Antwort
schlecki

Registriert seit: 11. Apr 2005
Ort: Darmstadt
148 Beiträge
 
Delphi XE2 Enterprise
 
#1

AW: Regionen ersetzen - fertige Funktionen?

  Alt 25. Mär 2011, 12:18
Hallo stahli,

vielleicht nochmal ein ganz anderer Ansatz:

du generierst deine Datei mit den Klassen (wird immer erzeugt!), zusätzlich wird eine weitere Datei erzeugt (aber nur, wenn noch nicht vorhanden!).

Beispiel:
Delphi-Quellcode:
unit odTournamentEventGenerator;
// Diese Datei darf nicht geändert werden,
// sie wird bei Änderungen an der Struktur
// jedes mal neu erzeugt.
{...}
type
  TodTournamentEventGenerated = class(TodOlympicCustom)
    {...}
  end;
Delphi-Quellcode:
unit odTournamentEvent;

// Geschäftslogik kommt in diese Datei.
// Diese wird nur erzeugt, wenn sie noch
// nicht vorhanden ist.

uses
  odTournamentEventGenerator;

interface

type
  TodTournamentEvent = class(TodTournamentEventGenerated)
    {...}
  end;
Das hat den Vorteil, dass du deine Geschäftslogik nicht aus dem generierten Code raussuchen musst.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

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

AW: Regionen ersetzen - fertige Funktionen?

  Alt 25. Mär 2011, 12:45
@Memnarch
Ich hatte, die Hoffnung, das hätte schon jemand irgendwo im Schubfach (aus einem CodeFormatter oder so)...

@Schlecki
Das war mein erster Ansatz. Da sich aber meine Klassen gegenseitig referenzieren (und bereits Instanzen erzeugen), müsste ich die erzeugten Objekte immer casten, um die Geschäftslogik nutzen zu können.
Mein zweiter Ansatz war dann, die Geschäftslogik in ClassHelper zu packen. Das hatte dann aber auch zu viele Einschränkungen und wurde auf Grund der vielzahl der genutzen Klassen mit der Zeit immer unübersichtlicher.
Im dritten Ansatz habe ich die generierten variablen Teile in Include-Dateien ausgelagert. Das hat zwar soweit perfekt funktioniert, ist aber im Handling etwas nervig. Die IDE und der Debuger haben mit den Includes teilw. etwas Probleme, weshalb ich nun die Regionen nutzen will.
Durch die Regionen sollte zum Einen mein Tool die generierten Bereiche erkennen können und diese zum Anderen auch im Quelltext nicht störend auffallen ... denke ich.
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.358 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Regionen ersetzen - fertige Funktionen?

  Alt 28. Mär 2011, 09:36
Falls es mal jemand brauchen kann, hier mal etwas als Grundlage:

Die Funktion interpretiert Quelltextteile (Code, StringKonstanten, Kommentare). In "Work" erfolgt dann die Verarbeitung der gefundenen Abschnitte.

Natürlich muss das jeder für seine Zwecke anpassen, aber so muss man vielleicht nicht bei 0 anfangen...


Delphi-Quellcode:
procedure TRegion.ScanRegions(var ScanCode: String; var P: Integer; BaseFlag: Boolean);
type
  TCodeType = (ctCode, ctConstant, ctCommentSL, ctCommentEM, ctCommentST);
  // ..............................slash .......embowed......star.......
var
  R, CR: String;
  CodeType: TCodeType;
  ExitFlag: Boolean;

  procedure Work(NewCodeType: TCodeType);
  var
    C, Id: String;
    P1, P2: Integer;
    NewRegion: TRegion;
    SL: TStringList;
    SS: String;
    PP: Integer;
  begin
    case CodeType of
      ctCode:
        begin
        end;
      ctConstant:
        begin
        end;
      ctCommentSL:
        begin
        end;
      ctCommentEM:
        begin
          C := '{$REGION';
          if PosEx(C, UpperCase(R)) = 1 then
          begin
            P1 := PosEx('''', R);
            P2 := PosEx('''', R, Succ(P1));
            if P2 > P1 then
            begin
              NewRegion := TRegion.Create(Self);
              RegionList.Add(NewRegion);
              NewRegion.Id := Copy(R, Succ(P1), Pred(P2 - P1));
              R := NewRegion.IncludeId;
              NewRegion.ScanRegions(ScanCode, P, False);
            end;
          end;
          C := '{$ENDREGION';
          if PosEx(C, UpperCase(R)) = 1 then
          begin
            R := '';
            ExitFlag := not BaseFlag;
            Exit;
          end;
          C := '{$INCLUDE';
          if PosEx(C, UpperCase(R)) = 1 then
          begin
            P1 := PosEx('''', R);
            P2 := PosEx('''', R, Succ(P1));
            if P2 > P1 then
            begin
              NewRegion := TRegion.Create(Self);
              RegionList.Add(NewRegion);
              NewRegion.Id := Copy(R, Succ(P1), Pred(P2 - P1));
              SL := TStringList.Create;
              SL.LoadFromFile(OldPath + NewRegion.Id);
              while Pos('_', NewRegion.Id) > 0 do
                NewRegion.Id := Copy(NewRegion.Id, Succ(Pos('_', NewRegion.Id)), MaxInt);
              while Pos('.', NewRegion.Id) > 0 do
                NewRegion.Id := Copy(NewRegion.Id, 1, Pred(Pos('.', NewRegion.Id)));
              if NewRegion.Id = 'privatvarthen
                NewRegion.Id := 'privat';
              R := NewRegion.IncludeId;
              SS := #13#10 + SL.Text;
              PP := 1;
              NewRegion.ScanRegions(SS, PP, True);
              FreeAndNil(SL);
              NewCodeType := ctCode;
            end;
          end;
        end;
      ctCommentST:
        begin
        end;
    end;
    // R := StringReplace(R, #13#10, ' ', [rfReplaceAll]);
    // OutputDebugString(PChar(R));
    CR := CR + R;
    R := '';
    CodeType := NewCodeType;
  end;

begin
  P := Max(P, 1);
  ExitFlag := False;
  CR := '';
  R := '';
  CodeType := ctCode;
  while P <= Length(ScanCode) do
  begin
    case CodeType of
      ctCode:
        begin
          if Copy(ScanCode, P, 2) = '//then
          begin
            Work(ctCommentSL);
            R := R + Copy(ScanCode, P, 2);
            Inc(P, 2);
          end
          else if Copy(ScanCode, P, 1) = '''then
          begin
            Work(ctConstant);
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
          end
          else if Copy(ScanCode, P, 1) = '{then
          begin
            Work(ctCommentEM);
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
          end
          else if Copy(ScanCode, P, 2) = '(*then
          begin
            Work(ctCommentST);
            R := R + Copy(ScanCode, P, 2);
            Inc(P, 2);
          end
          else
          begin
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
          end;
        end;
      ctConstant:
        begin
          if Copy(ScanCode, P, 1) = '''then
          begin
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
            Work(ctCode);
          end
          else
          begin
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
          end;
        end;
      ctCommentSL:
        begin
          if Copy(ScanCode, P, 2) = #13#10 then
          begin
            Work(ctCode);
            R := R + Copy(ScanCode, P, 2);
            Inc(P, 2);
          end
          else
          begin
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
          end;
        end;
      ctCommentEM:
        begin
          if Copy(ScanCode, P, 1) = '}then
          begin
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
            Work(ctCode);
          end
          else
          begin
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
          end;
        end;
      ctCommentST:
        begin
          if Copy(ScanCode, P, 2) = '*)then
          begin
            R := R + Copy(ScanCode, P, 2);
            Inc(P, 2);
            Work(ctCode);
          end
          else
          begin
            R := R + Copy(ScanCode, P, 1);
            Inc(P);
          end;
        end;
    end;
    if ExitFlag then
    begin
      Code := CR;
      Exit;
    end;
  end;
  Work(ctCode);
  Code := CR;
end;
TRegion ist meine Komponente.
ScanRegions analysiert den Quelltext, der in ScanCode steht.
P muss zu beginn 1 sein.
BaseFlag=True, heißt, dass die Unit (und keine Unterregion) interpretiert wird.
Es werden Quelltext, StringKonstanten und Kommentare herausgelesen.
Die Reaktion auf gefundene Teile erfolgt in Work (das muss also jeder für sich anpassen).
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Antwort Antwort


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 04:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz