Inhaltsverzeichnis

Convenzioni del codice

Standard di codifica vincolanti per la suite WvdS FPC RAD.

Convenzioni di naming

Tipi

Categoria Prefisso Esempio
Classe TWvdS* TWvdSBuildConfig, TWvdSProjectManager
Interface IWvdS* IWvdSLogger, IWvdSParser
Record TWvdS* TWvdSBuildResult, TWvdSToolPath
Enum TWvdS* TWvdSProjectType, TWvdSBuildStatus
Exception EWvdS* EWvdSFileNotFound, EWvdSParseError
Callback TWvdS* TWvdSBuildCallback, TWvdSProgressHandler
I tipi API esterni (VSCode, Node.js) mantengono i loro nomi originali.

Nomi delle unit

Namespace stile Microsoft con prefisso WvdS:

WvdS.{Domain}.{Layer}.pas

Esempi:
WvdS.Build.Models.pas
WvdS.Build.Service.pas
WvdS.Projects.SettingsDialog.pas
WvdS.VSCode.Commands.pas

Suffissi layer

Suffisso Contenuto Esempio
.Models Record, enum, tipi WvdS.Build.Models
.Service Logica di business WvdS.Build.Service
.Dialog Dialoghi WebView WvdS.Projects.SettingsDialog
.Provider Wrapper API VSCode WvdS.Designer.EditorProvider

Variabili e parametri

Categoria Prefisso Esempio
Campi privati F FProjectPath, FConfig
Parametri A APath, AOptions, ACallback
Variabili locali Nessuno Result, I, Config

Resourcestrings

Prefisso per feature:

Prefisso Feature
rsCore* Estensione Core
rsBuild* Estensione Build
rsProject* Estensione Projects
rsDesigner* UI Designer
rsPreview* UI Preview
rsMeta* UI Meta
rsPackaging* Packaging
rsTool* Toolchain

Struttura del codice

Struttura unit

unit WvdS.{Feature}.{Layer};
 
{$mode objfpc}{$H+}
 
interface
 
uses
  // 1. Unit di sistema
  SysUtils, Classes,
  // 2. WvdS Common
  WvdS.System, WvdS.Collections,
  // 3. Specifiche della feature
  WvdS.{Feature}.Models;
 
type
  // Definizioni di tipo
 
function PublicFunction(const AParam: string): Boolean;
procedure PublicProcedure(AValue: Integer);
 
implementation
 
uses
  // Uses privati (unit necessarie solo qui)
  WvdS.VSCode.Strings;
 
// Tipi e variabili private
type
  TInternalHelper = class
  end;
 
var
  InternalState: TObject;
 
// Implementazioni
 
function PublicFunction(const AParam: string): Boolean;
begin
  // ...
end;
 
procedure PublicProcedure(AValue: Integer);
begin
  // ...
end;
 
initialization
  // Inizializzazione
 
finalization
  // Pulizia
 
end.

Struttura classe

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;

Documentazione

Formato PasDoc

(*
  @abstract(Breve descrizione in una frase.)
 
  Descrizione dettagliata dello scopo e dell'utilizzo.
  Puo comprendere piu frasi.
 
  @param(APath Percorso completo del file)
  @param(AOptions Configurazione opzionale, puo essere nil)
  @returns(True se successo, False in caso di errore)
 
  @raises(EWvdSFileNotFound se il file non esiste)
  @raises(EWvdSAccessDenied se non ci sono permessi di lettura)
 
  Security:
    - CWE-22: Il percorso viene validato contro Path Traversal
 
  @seealso(RelatedFunction)
  @seealso(TWvdSRelatedClass)
*)
function ProcessFile(const APath: string; AOptions: TOptions): Boolean;

Commenti inline

// Commento breve per singola riga
Result := CalculateValue;
 
// Commento multiriga per logica piu complessa
// Spiega il perche, non il cosa
if (Value > Threshold) and (Mode = mAdvanced) then
begin
  // Dobbiamo usare l'algoritmo avanzato qui,
  // perche quello semplice diventa impreciso con valori grandi
  Result := AdvancedCalculation(Value);
end;

Costanti invece di magic number

// VIETATO
if Length(Name) > 64 then
if Timeout > 30000 then
 
// CORRETTO
const
  MAX_PROJECT_NAME_LENGTH = 64;
  DEFAULT_TIMEOUT_MS = 30000;
 
if Length(Name) > MAX_PROJECT_NAME_LENGTH then
if Timeout > DEFAULT_TIMEOUT_MS then

Terminologia

Usare termini consistenti:

Usa Evita
Path Url, Location, Dir (inconsistente)
Config Settings, Options, Prefs (inconsistente)
Create Make, Build (per oggetti)
Generate Create (per output)
Validate Check, Verify (per input)
Initialize Setup, Init (inconsistente)
Execute Run, Process (inconsistente)

Formattazione

Indentazione

// CORRETTO
procedure Example;
begin
  if Condition then
  begin
    DoSomething;
    DoMore;
  end
  else
  begin
    DoAlternative;
  end;
end;
 
// VIETATO
procedure Example; begin
  if Condition then begin DoSomething; DoMore; end
  else DoAlternative;
end;

Lunghezza riga

// Per liste parametri lunghe
function VeryLongFunctionName(
  const AFirstParameter: string;
  const ASecondParameter: Integer;
  AThirdParameter: TOptions
): Boolean;
 
// Per condizioni lunghe
if (FirstCondition) and
   (SecondCondition) and
   (ThirdCondition) then
begin
  // ...
end;

Pattern vietati

Handler eccezioni vuoti

// VIETATO
try
  DoSomething;
except
  // Non fare nulla - ingoiare l'errore!
end;
 
// CORRETTO
try
  DoSomething;
except
  on E: Exception do
    LogError(rsUnexpectedError, [E.ClassName, E.Message]);
end;

TODO/FIXME nel codice di produzione

// VIETATO nel branch main
// TODO: Implement this later
// FIXME: This is broken
 
// CONSENTITO solo in branch feature, deve essere rimosso prima del merge

Stringhe hardcoded

// VIETATO
ShowMessage('File not found');
ShowMessage('File non trovato');
 
// CORRETTO
ShowMessage(rsFileNotFound);  // resourcestring

Variabili globali nei service

// VIETATO
var
  GlobalConfig: TConfig;  // Difficile da testare!
 
// CORRETTO - passare parametri
function ProcessWithConfig(const AConfig: TConfig): Boolean;

Testabilita

I service devono essere testabili senza VSCode/UI:

// VIETATO - UI nel service
procedure ValidateAndShowError(const AName: string);
begin
  if not IsValid(AName) then
    ShowMessage('Invalid name');  // Dipendenza UI!
end;
 
// CORRETTO - valore di ritorno
function ValidateName(const AName: string; out AError: string): Boolean;
begin
  Result := IsValid(AName);
  if not Result then
    AError := rsInvalidName;
end;

Compatibilita pas2js (IMPORTANTE)

pas2js NON e 100% compatibile con FPC! Queste limitazioni DEVONO essere rispettate.

Feature non supportate

Feature FPC pas2js Workaround
class var OK No Usare variabile a livello unit
var inline OK No Dichiarare nel blocco var
Int64 OK No Usare Integer