Inhaltsverzeichnis
Code-Konventionen
Verbindliche Coding-Standards für die WvdS FPC RAD Suite.
Namenskonventionen
Typen
| Kategorie | Präfix | Beispiel |
|---|---|---|
| Klasse | TWvdS* | TWvdSBuildConfig, TWvdSProjectManager |
| Interface | IWvdS* | IWvdSLogger, IWvdSParser |
| Record | TWvdS* | TWvdSBuildResult, TWvdSToolPath |
| Enum | TWvdS* | TWvdSProjectType, TWvdSBuildStatus |
| Exception | EWvdS* | EWvdSFileNotFound, EWvdSParseError |
| Callback | TWvdS* | TWvdSBuildCallback, TWvdSProgressHandler |
Externe API-Typen (VSCode, Node.js) behalten ihre originalen Namen.
Unit-Namen
Microsoft-Stil Namespaces mit WvdS-Präfix:
WvdS.{Domain}.{Layer}.pas
Beispiele:
WvdS.Build.Models.pas
WvdS.Build.Service.pas
WvdS.Projects.SettingsDialog.pas
WvdS.VSCode.Commands.pas
Layer-Suffixe
| Suffix | Inhalt | Beispiel |
|---|---|---|
| .Models | Records, Enums, Typen | WvdS.Build.Models |
| .Service | Geschäftslogik | WvdS.Build.Service |
| .Dialog | WebView-Dialoge | WvdS.Projects.SettingsDialog |
| .Provider | VSCode API Wrapper | WvdS.Designer.EditorProvider |
Variablen und Parameter
| Kategorie | Präfix | Beispiel |
|---|---|---|
| Private Felder | F | FProjectPath, FConfig |
| Parameter | A | APath, AOptions, ACallback |
| Lokale Variablen | Kein | Result, I, Config |
Resourcestrings
Präfix nach Feature:
| Präfix | Feature |
|---|---|
| rsCore* | Core Extension |
| rsBuild* | Build Extension |
| rsProject* | Projects Extension |
| rsDesigner* | UI Designer |
| rsPreview* | UI Preview |
| rsMeta* | UI Meta |
| rsPackaging* | Packaging |
| rsTool* | Toolchain |
Code-Struktur
Unit-Aufbau
unit WvdS.{Feature}.{Layer}; {$mode objfpc}{$H+} interface uses // 1. System Units SysUtils, Classes, // 2. WvdS Common WvdS.System, WvdS.Collections, // 3. Feature-spezifisch WvdS.{Feature}.Models; type // Typ-Definitionen function PublicFunction(const AParam: string): Boolean; procedure PublicProcedure(AValue: Integer); implementation uses // Private Uses (nur hier benötigte Units) WvdS.VSCode.Strings; // Private Typen und Variablen type TInternalHelper = class end; var InternalState: TObject; // Implementierungen function PublicFunction(const AParam: string): Boolean; begin // ... end; procedure PublicProcedure(AValue: Integer); begin // ... end; initialization // Initialisierung finalization // Aufräumen end.
Klassen-Aufbau
type TWvdSExampleClass = class(TObject) private FName: string; FValue: Integer; procedure SetName(const AValue: string); protected procedure DoInternalWork; virtual; public constructor Create(const AName: string); destructor Destroy; override; procedure Execute; property Name: string read FName write SetName; property Value: Integer read FValue write FValue; end;
Dokumentation
PasDoc-Format
(* @abstract(Kurze Beschreibung in einem Satz.) Ausführliche Beschreibung des Zwecks und der Verwendung. Kann mehrere Sätze umfassen. @param(APath Vollständiger Pfad zur Datei) @param(AOptions Optionale Konfiguration, kann nil sein) @returns(True wenn erfolgreich, False bei Fehler) @raises(EWvdSFileNotFound wenn Datei nicht existiert) @raises(EWvdSAccessDenied wenn keine Leserechte) Security: - CWE-22: Pfad wird gegen Path Traversal validiert @seealso(RelatedFunction) @seealso(TWvdSRelatedClass) *) function ProcessFile(const APath: string; AOptions: TOptions): Boolean;
Inline-Kommentare
// Kurzer Kommentar für einzelne Zeile Result := CalculateValue; // Mehrzeiliger Kommentar für komplexere Logik // Erklärt den Grund, nicht das Was if (Value > Threshold) and (Mode = mAdvanced) then begin // Wir müssen hier den erweiterten Algorithmus verwenden, // da der einfache bei großen Werten ungenau wird Result := AdvancedCalculation(Value); end;
Konstanten statt Magic Numbers
// VERBOTEN if Length(Name) > 64 then if Timeout > 30000 then // KORREKT const MAX_PROJECT_NAME_LENGTH = 64; DEFAULT_TIMEOUT_MS = 30000; if Length(Name) > MAX_PROJECT_NAME_LENGTH then if Timeout > DEFAULT_TIMEOUT_MS then
Terminologie
Konsistente Begriffe verwenden:
| Verwende | Vermeide |
|---|---|
| Path | Url, Location, Dir (inkonsistent) |
| Config | Settings, Options, Prefs (inkonsistent) |
| Create | Make, Build (für Objekte) |
| Generate | Create (für Ausgabe) |
| Validate | Check, Verify (für Eingaben) |
| Initialize | Setup, Init (inkonsistent) |
| Execute | Run, Process (inkonsistent) |
Formatierung
Einrückung
- 2 Spaces für Einrückung (nicht Tabs)
- begin auf eigener Zeile bei Blöcken
- end auf gleicher Einrückungsebene wie zugehöriges begin
// KORREKT procedure Example; begin if Condition then begin DoSomething; DoMore; end else begin DoAlternative; end; end; // VERBOTEN procedure Example; begin if Condition then begin DoSomething; DoMore; end else DoAlternative; end;
Zeilenlänge
- Maximum 120 Zeichen pro Zeile
- Bei langen Ausdrücken umbrechen
// Bei langen Parameterlisten function VeryLongFunctionName( const AFirstParameter: string; const ASecondParameter: Integer; AThirdParameter: TOptions ): Boolean; // Bei langen Bedingungen if (FirstCondition) and (SecondCondition) and (ThirdCondition) then begin // ... end;
Verbotene Patterns
Leere Exception-Handler
// VERBOTEN try DoSomething; except // Nichts tun - Fehler verschlucken! end; // KORREKT try DoSomething; except on E: Exception do LogError(rsUnexpectedError, [E.ClassName, E.Message]); end;
TODO/FIXME im Produktionscode
// VERBOTEN in main-Branch // TODO: Implement this later // FIXME: This is broken // ERLAUBT nur in Feature-Branches, muß vor Merge entfernt werden
Hardcodierte Strings
// VERBOTEN ShowMessage('File not found'); ShowMessage('Datei nicht gefunden'); // KORREKT ShowMessage(rsFileNotFound); // resourcestring
Globale Variablen in Services
// VERBOTEN var GlobalConfig: TConfig; // Schwer testbar! // KORREKT - Parameter übergeben function ProcessWithConfig(const AConfig: TConfig): Boolean;
Testbarkeit
Services müssen ohne VSCode/UI testbar sein:
// VERBOTEN - UI in Service procedure ValidateAndShowError(const AName: string); begin if not IsValid(AName) then ShowMessage('Invalid name'); // UI-Abhängigkeit! end; // KORREKT - Rückgabewert function ValidateName(const AName: string; out AError: string): Boolean; begin Result := IsValid(AName); if not Result then AError := rsInvalidName; end;
pas2js Kompatibilität (WICHTIG)
pas2js ist NICHT 100% kompatibel mit FPC! Diese Einschränkungen MÜSSEN beachtet werden.
Nicht unterstützte Features
| Feature | FPC | pas2js | Workaround |
|---|---|---|---|
class var | ✓ | ✗ | Unit-Level Variable verwenden |
Inline var | ✓ | ✗ | Im var-Block deklarieren |
Int64 | ✓ | ✗ | Integer verwenden |
Zuletzt geändert: den 29.01.2026 um 15:13