Inhaltsverzeichnis
Code Conventions
Mandatory coding standards for the WvdS FPC RAD Suite.
Naming Conventions
Types
| Category | Prefix | Example |
|---|---|---|
| Class | TWvdS* | TWvdSBuildConfig, TWvdSProjectManager |
| Interface | IWvdS* | IWvdSLogger, IWvdSParser |
| Record | TWvdS* | TWvdSBuildResult, TWvdSToolPath |
| Enum | TWvdS* | TWvdSProjectType, TWvdSBuildStatus |
| Exception | EWvdS* | EWvdSFileNotFound, EWvdSParseError |
| Callback | TWvdS* | TWvdSBuildCallback, TWvdSProgressHandler |
External API types (VSCode, Node.js) retain their original names.
Unit Names
Microsoft-style namespaces with WvdS prefix:
WvdS.{Domain}.{Layer}.pas
Examples:
WvdS.Build.Models.pas
WvdS.Build.Service.pas
WvdS.Projects.SettingsDialog.pas
WvdS.VSCode.Commands.pas
Layer Suffixes
| Suffix | Content | Example |
|---|---|---|
| .Models | Records, enums, types | WvdS.Build.Models |
| .Service | Business logic | WvdS.Build.Service |
| .Dialog | WebView dialogs | WvdS.Projects.SettingsDialog |
| .Provider | VSCode API wrapper | WvdS.Designer.EditorProvider |
Variables and Parameters
| Category | Prefix | Example |
|---|---|---|
| Private fields | F | FProjectPath, FConfig |
| Parameters | A | APath, AOptions, ACallback |
| Local variables | None | Result, I, Config |
Resourcestrings
Prefix by feature:
| Prefix | Feature |
|---|---|
| rsCore* | Core Extension |
| rsBuild* | Build Extension |
| rsProject* | Projects Extension |
| rsDesigner* | UI Designer |
| rsPreview* | UI Preview |
| rsMeta* | UI Meta |
| rsPackaging* | Packaging |
| rsTool* | Toolchain |
Code Structure
Unit Layout
unit WvdS.{Feature}.{Layer}; {$mode objfpc}{$H+} interface uses // 1. System Units SysUtils, Classes, // 2. WvdS Common WvdS.System, WvdS.Collections, // 3. Feature-specific WvdS.{Feature}.Models; type // Type definitions function PublicFunction(const AParam: string): Boolean; procedure PublicProcedure(AValue: Integer); implementation uses // Private uses (units needed only here) WvdS.VSCode.Strings; // Private types and variables type TInternalHelper = class end; var InternalState: TObject; // Implementations function PublicFunction(const AParam: string): Boolean; begin // ... end; procedure PublicProcedure(AValue: Integer); begin // ... end; initialization // Initialization finalization // Cleanup end.
Class Layout
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;
Documentation
PasDoc Format
(* @abstract(Short description in one sentence.) Detailed description of purpose and usage. Can span multiple sentences. @param(APath Full path to the file) @param(AOptions Optional configuration, can be nil) @returns(True if successful, False on error) @raises(EWvdSFileNotFound when file does not exist) @raises(EWvdSAccessDenied when no read permissions) Security: - CWE-22: Path is validated against path traversal @seealso(RelatedFunction) @seealso(TWvdSRelatedClass) *) function ProcessFile(const APath: string; AOptions: TOptions): Boolean;
Inline Comments
// Short comment for single line Result := CalculateValue; // Multi-line comment for more complex logic // Explains the why, not the what if (Value > Threshold) and (Mode = mAdvanced) then begin // We need to use the advanced algorithm here, // as the simple one becomes inaccurate for large values Result := AdvancedCalculation(Value); end;
Constants Instead of Magic Numbers
// FORBIDDEN if Length(Name) > 64 then if Timeout > 30000 then // CORRECT const MAX_PROJECT_NAME_LENGTH = 64; DEFAULT_TIMEOUT_MS = 30000; if Length(Name) > MAX_PROJECT_NAME_LENGTH then if Timeout > DEFAULT_TIMEOUT_MS then
Terminology
Use consistent terms:
| Use | Avoid |
|---|---|
| Path | Url, Location, Dir (inconsistent) |
| Config | Settings, Options, Prefs (inconsistent) |
| Create | Make, Build (for objects) |
| Generate | Create (for output) |
| Validate | Check, Verify (for inputs) |
| Initialize | Setup, Init (inconsistent) |
| Execute | Run, Process (inconsistent) |
Formatting
Indentation
- 2 Spaces for indentation (not tabs)
- begin on its own line for blocks
- end at the same indentation level as the corresponding begin
// CORRECT procedure Example; begin if Condition then begin DoSomething; DoMore; end else begin DoAlternative; end; end; // FORBIDDEN procedure Example; begin if Condition then begin DoSomething; DoMore; end else DoAlternative; end;
Line Length
- Maximum 120 characters per line
- Wrap long expressions
// For long parameter lists function VeryLongFunctionName( const AFirstParameter: string; const ASecondParameter: Integer; AThirdParameter: TOptions ): Boolean; // For long conditions if (FirstCondition) and (SecondCondition) and (ThirdCondition) then begin // ... end;
Forbidden Patterns
Empty Exception Handlers
// FORBIDDEN try DoSomething; except // Do nothing - swallowing errors! end; // CORRECT try DoSomething; except on E: Exception do LogError(rsUnexpectedError, [E.ClassName, E.Message]); end;
TODO/FIXME in Production Code
// FORBIDDEN in main branch // TODO: Implement this later // FIXME: This is broken // ALLOWED only in feature branches, must be removed before merge
Hardcoded Strings
// FORBIDDEN ShowMessage('File not found'); ShowMessage('Datei nicht gefunden'); // CORRECT ShowMessage(rsFileNotFound); // resourcestring
Global Variables in Services
// FORBIDDEN var GlobalConfig: TConfig; // Hard to test! // CORRECT - Pass parameters function ProcessWithConfig(const AConfig: TConfig): Boolean;
Testability
Services must be testable without VSCode/UI:
// FORBIDDEN - UI in Service procedure ValidateAndShowError(const AName: string); begin if not IsValid(AName) then ShowMessage('Invalid name'); // UI dependency! end; // CORRECT - Return value function ValidateName(const AName: string; out AError: string): Boolean; begin Result := IsValid(AName); if not Result then AError := rsInvalidName; end;
pas2js Compatibility (IMPORTANT)
pas2js is NOT 100% compatible with FPC! These restrictions MUST be observed.
Unsupported Features
| Feature | FPC | pas2js | Workaround |
|---|---|---|---|
class var | Yes | No | Use unit-level variable |
Inline var | Yes | No | Declare in var block |
Int64 | Yes | No | Use Integer |
Zuletzt geändert: on 2026/01/29 at 10:29 PM