paxCompiler/Sources/PAXCOMP_GENERIC.pas
Dalibor Marković 9d0de424e8
Init
Signed-off-by: Dalibor Marković <dalibor31@gmail.com>
2024-07-06 22:28:12 +02:00

1030 lines
24 KiB
ObjectPascal

////////////////////////////////////////////////////////////////////////////
// PaxCompiler
// Site: http://www.paxcompiler.com
// Author: Alexander Baranovsky (paxscript@gmail.com)
// ========================================================================
// Copyright (c) Alexander Baranovsky, 2006-2014. All rights reserved.
// Code Version: 4.2
// ========================================================================
// Unit: PAXCOMP_GENERIC.pas
// ========================================================================
////////////////////////////////////////////////////////////////////////////
{$I PaxCompiler.def}
unit PAXCOMP_GENERIC;
interface
uses {$I uses.def}
Classes,
SysUtils,
PAXCOMP_CONSTANTS,
PAXCOMP_TYPES,
PAXCOMP_SYS;
type
TGenericTypeContainer = class;
TTypeParams = class(TStringObjectList)
public
procedure AssTo(L: TTypeParams);
end;
TTypeParamsHistory = class(TTypedList)
private
function GetRecord(I: Integer): TTypeParams;
public
function Add(const Value: TTypeParams): TTypeParams;
property Records[I: Integer]: TTypeParams read GetRecord; default;
end;
TTypeRestrictionRec = class
public
Id: Integer;
N: Integer;
function Clone: TTypeRestrictionRec;
end;
TTypeRec = class
public
Name: String;
ParamList: TTypeParams;
IsExtra: Boolean;
IsGeneric: Boolean;
constructor Create;
destructor Destroy; override;
end;
TTypeExpRec = class(TTypeRec);
TTypeExtRec = class(TTypeRec)
public
P1, P2: Integer;
LangId: Integer;
Extension: String;
Valid: Boolean;
function Substitute(R: TTypeExpRec): String;
end;
TTypeExtList = class(TTypedList)
private
function GetRecord(I: Integer): TTypeExtRec;
function GetTop: TTypeExtRec;
public
function Add: TTypeExtRec;
property Top: TTypeExtRec read GetTop;
property Records[I: Integer]: TTypeExtRec read GetRecord; default;
end;
TTypeDefRec = class(TTypeRec)
public
P1, P2: Integer;
LangId: Integer;
TypeId: Integer;
SubId: Integer;
Definition: String;
IsMethodImplementation: Boolean; // Pascal only
AncestorName: String;
TypeExtList: TTypeExtList;
ModuleName: String;
function Substitute(R: TTypeExpRec): String;
constructor Create(AModuleName: String; ALangId: Integer);
destructor Destroy; override;
end;
TTypeExpList = class(TTypedList)
private
function GetRecord(I: Integer): TTypeExpRec;
function GetTop: TTypeExpRec;
public
constructor Create;
function IndexOf(const TypeName: String;
TypeParams: TStrings;
Upcase: Boolean): Integer;
function Add: TTypeExpRec;
property Top: TTypeExpRec read GetTop;
property Records[I: Integer]: TTypeExpRec read GetRecord; default;
end;
TTypeModuleRec = class
public
ModuleName: String;
LangId: Integer;
UsingList: TStringList;
Source: String;
Success: Boolean;
constructor Create;
destructor Destroy; override;
end;
TTypeModuleList = class(TTypedList)
private
function GetRecord(I: Integer): TTypeModuleRec;
public
function IndexOf(const ModuleName: String): Integer;
function AddModule(const ModuleName: String; LangId: Integer): TTypeModuleRec;
property Records[I: Integer]: TTypeModuleRec read GetRecord; default;
end;
TTypeDefList = class(TTypedList)
private
procedure RaiseError(const Message: string; params: array of Const);
function GetRecord(I: Integer): TTypeDefRec;
function GetTop: TTypeDefRec;
procedure TryExpansion(const TypeName: String;
LangId: Integer;
result: TStringList;
var Success: Boolean;
I, J: Integer);
public
TypeExpList: TTypeExpList;
Expansions: TAssocIntegers;
RemTypeIds: TIntegerList;
TypeModuleList: TTypeModuleList;
CurrTypeModuleRec: TTypeModuleRec;
constructor Create;
destructor Destroy; override;
function IndexOf(const TypeName: String;
TypeParams: TStringList;
Upcase: Boolean): Integer;
function Add(const ModuleName: String; LangId: Integer): TTypeDefRec;
function FindTypeDef(TypeId: Integer): TTypeDefRec;
function FindMethodDef(SubId: Integer): TTypeDefRec;
procedure Clear; override;
procedure ReplaceId(OldId, NewId: Integer);
procedure GenPascalUnits;
procedure GenBasicUnits;
procedure GenJavaUnits;
procedure CreateConainer(TypeId: Integer; result: TGenericTypeContainer);
property Top: TTypeDefRec read GetTop;
property Records[I: Integer]: TTypeDefRec read GetRecord; default;
end;
TGenericTypeContainer = class
public
Definition: String;
MethodList: TStringList;
constructor Create;
destructor Destroy; override;
procedure SaveToStream(S: TStream);
procedure LoadFromStream(S: TStream);
end;
implementation
function GetExtraPascalUnitName(const ModuleName: String): String;
begin
result := strExtraPascalUnit + ExtractName(ModuleName);
end;
function GetExtraBasicUnitName(const ModuleName: String): String;
begin
result := strExtraBasicUnit + ExtractName(ModuleName);
end;
function GetExtraJavaUnitName(const ModuleName: String): String;
begin
result := strExtraJavaUnit + ExtractName(ModuleName);
end;
function Substitute(const S: String; P1, P2: TTypeParams): String;
var
I: Integer;
Name1, Name2: String;
begin
if P1.Count <> P2.Count then
raise Exception.Create(errInternalError);
result := S;
for I := 0 to P1.Count - 1 do
begin
Name1 := P1[I];
Name2 := P2[I];
result := Subst(result, Name1, Name2);
end;
end;
function TTypeExtRec.Substitute(R: TTypeExpRec): String;
var
I: Integer;
Name1, Name2: String;
begin
if ParamList.Count <> R.ParamList.Count then
raise Exception.Create(errInternalError);
result := Extension;
for I := 0 to ParamList.Count - 1 do
begin
Name1 := ParamList[I];
Name2 := R.ParamList[I];
result := Subst(result, Name1, Name2);
end;
end;
// TTypeExtList ----------------------------------------------------------------
function TTypeExtList.GetRecord(I: Integer): TTypeExtRec;
begin
result := TTypeExtRec(L[I]);
end;
function TTypeExtList.Add: TTypeExtRec;
begin
result := TTypeExtRec.Create;
L.Add(result);
end;
function TTypeExtList.GetTop: TTypeExtRec;
begin
result := Records[Count - 1];
end;
// TTypeRec --------------------------------------------------------------------
constructor TTypeRec.Create;
begin
inherited;
ParamList := TTypeParams.Create;
end;
destructor TTypeRec.Destroy;
begin
ParamList.Free;
inherited;
end;
function TTypeRestrictionRec.Clone: TTypeRestrictionRec;
begin
result := TTypeRestrictionRec.Create;
result.Id := Id;
result.N := N;
end;
constructor TTypeDefRec.Create(AModuleName: String; ALangId: Integer);
begin
inherited Create;
ModuleName := AModuleName;
LangId := ALangId;
TypeExtList := TTypeExtList.Create;
end;
destructor TTypeDefRec.Destroy;
begin
TypeExtList.Free;
inherited;
end;
function TTypeDefRec.Substitute(R: TTypeExpRec): String;
var
I: Integer;
Name1, Name2: String;
begin
if ParamList.Count <> R.ParamList.Count then
raise Exception.Create(errInternalError);
result := Definition;
for I := 0 to ParamList.Count - 1 do
begin
Name1 := ParamList[I];
Name2 := R.ParamList[I];
result := Subst(result, Name1, Name2);
end;
end;
// TTypeExpList ----------------------------------------------------------------
constructor TTypeExpList.Create;
begin
inherited Create;
end;
function TTypeExpList.GetRecord(I: Integer): TTypeExpRec;
begin
result := TTypeExpRec(L[I]);
end;
function TTypeExpList.IndexOf(const TypeName: String;
TypeParams: TStrings;
Upcase: Boolean): Integer;
var
I, J: Integer;
R: TTypeExpRec;
b, b1, b2: Boolean;
S1, S2: String;
begin
result := -1;
for I := 0 to Count - 1 do
begin
R := Records[I];
if Upcase then
b1 := StrEql(R.Name, TypeName)
else
b1 := R.Name = TypeName;
if b1 then
if R.ParamList.Count = TypeParams.Count then
begin
b := true;
for J := 0 to R.ParamList.Count - 1 do
begin
S1 := ExtractName(R.ParamList[J]);
S2 := ExtractName(TypeParams[J]);
if Upcase then
b2 := StrEql(S1, S2)
else
b2 := S1 = S2;
if not b2 then
begin
b := false;
break;
end;
end;
if b then
begin
result := I;
Exit;
end;
end;
end;
end;
function TTypeExpList.Add: TTypeExpRec;
begin
result := TTypeExpRec.Create;
L.Add(result);
end;
function TTypeExpList.GetTop: TTypeExpRec;
begin
result := Records[Count - 1];
end;
// TTypeDefList ----------------------------------------------------------------
constructor TTypeDefList.Create;
begin
inherited Create;
TypeExpList := TTypeExpList.Create;
Expansions := TAssocIntegers.Create;
RemTypeIds := TIntegerList.Create;
TypeModuleList := TTypeModuleList.Create;
end;
destructor TTypeDefList.Destroy;
begin
inherited;
Expansions.Free;
TypeExpList.Free;
RemTypeIds.Free;
TypeModuleList.Free;
end;
procedure TTypeDefList.Clear;
begin
Expansions.Clear;
TypeExpList.Clear;
RemTypeIds.Clear;
inherited;
end;
function TTypeDefList.GetRecord(I: Integer): TTypeDefRec;
begin
result := TTypeDefRec(L[I]);
end;
procedure TTypeDefList.RaiseError(const Message: string; params: array of Const);
begin
raise PaxCompilerException.Create(Format(Message, params));
end;
function TTypeDefList.IndexOf(const TypeName: String;
TypeParams: TStringList;
Upcase: Boolean): Integer;
var
I, J: Integer;
R: TTypeDefRec;
b, b1, b2: Boolean;
S1, S2: String;
begin
result := -1;
for I := 0 to Count - 1 do
begin
R := Records[I];
if Upcase then
b1 := StrEql(R.Name, TypeName)
else
b1 := R.Name = TypeName;
if b1 then
if R.ParamList.Count = TypeParams.Count then
begin
b := true;
for J := 0 to R.ParamList.Count - 1 do
begin
S1 := R.ParamList[J];
S2 := TypeParams[J];
if Upcase then
b2 := StrEql(S1, S2)
else
b2 := S1 = S2;
if not b2 then
begin
b := false;
break;
end;
end;
if b then
begin
result := I;
Exit;
end;
end;
end;
end;
function TTypeDefList.Add(const ModuleName: String; LangId: Integer): TTypeDefRec;
var
I: Integer;
begin
result := TTypeDefRec.Create(ModuleName, LangId);
L.Add(result);
I := TypeModuleList.IndexOf(ModuleName);
if I = -1 then
CurrTypeModuleRec := TypeModuleList.AddModule(ModuleName, LangId);
end;
function TTypeDefList.FindTypeDef(TypeId: Integer): TTypeDefRec;
var
I: Integer;
begin
result := nil;
for I := 0 to Count - 1 do
if Records[I].TypeId = TypeId then
begin
result := Records[I];
Exit;
end;
RaiseError(errInternalError, []);
end;
function TTypeDefList.FindMethodDef(SubId: Integer): TTypeDefRec;
var
I: Integer;
begin
result := nil;
for I := 0 to Count - 1 do
if Records[I].SubId = SubId then
begin
result := Records[I];
Exit;
end;
RaiseError(errInternalError, []);
end;
function TTypeDefList.GetTop: TTypeDefRec;
begin
result := Records[Count - 1];
end;
procedure TTypeDefList.ReplaceId(OldId, NewId: Integer);
var
I, J, K, L: Integer;
ParamList: TStringObjectList;
TR: TTypeRestrictionRec;
begin
for I := 0 to Count - 1 do
begin
ParamList := Records[I].ParamList;
for J := 0 to ParamList.Count - 1 do
begin
TR := TTypeRestrictionRec(ParamList.Objects[J]);
if TR <> nil then
if TR.Id = OldId then
TR.Id := NewId;
for K := 0 to Records[I].TypeExtList.Count - 1 do
begin
for L := 0 to Records[I].TypeExtList[K].ParamList.Count - 1 do
begin
TR := TTypeRestrictionRec(Records[I].TypeExtList[K].ParamList.Objects[L]);
if TR <> nil then
if TR.Id = OldId then
TR.Id := NewId;
end;
end;
end;
end;
for I := 0 to TypeExpList.Count - 1 do
begin
ParamList := TypeExpList[I].ParamList;
for J := 0 to ParamList.Count - 1 do
begin
TR := TTypeRestrictionRec(ParamList.Objects[J]);
if TR <> nil then
if TR.Id = OldId then
TR.Id := NewId;
end;
end;
end;
procedure TTypeDefList.TryExpansion(const TypeName: String;
LangId: Integer;
result: TStringList;
var Success: Boolean;
I, J: Integer);
var
RI, RL: TTypeExpRec;
RJ: TTypeDefRec;
RK: TTypeExtRec;
S, Q, S1: String;
K, L: Integer;
begin
RI := TypeExpList[I];
RJ := Records[J];
if RJ.IsExtra then
Exit;
if not RJ.IsGeneric then
Exit;
if RJ.LangId = LangId then
if not RJ.IsMethodImplementation then
if RI.ParamList.Count = RJ.ParamList.Count then
if StrEql(TypeName, RJ.Name) then
begin
Success := true;
if RJ.AncestorName <> '' then
begin
for K:=0 to Count - 1 do
if Expansions.IndexOf(I, K) = -1 then
TryExpansion(RJ.AncestorName,
LangId,
result,
Success,
I, K);
end;
S := RJ.Substitute(RI);
if RJ.TypeExtList.Count > 0 then
begin
if LangId = PASCAL_LANGUAGE then
begin
S1 := Copy(S, 1, Length(S) - 4);
for K := 0 to RJ.TypeExtList.Count - 1 do
begin
RK := RJ.TypeExtList[K];
for L := 0 to TypeExpList.Count - 1 do
begin
RL := TypeExpList[L];
if RK.ParamList.Count = RL.ParamList.Count then
if StrEql(RK.Name, RL.Name) then
begin
Q := Substitute(RK.Extension, RJ.ParamList, RI.ParamList);
Q := Substitute(Q, RK.ParamList, RL.ParamList);
Q := EXTRA_KEYWORD + ' ' + Q;
S1 := S1 + Q + #13#10;
end;
end;
end;
S := S1 + 'end;';
end;
end;
result.Add(S);
Expansions.Add(I, J);
end;
end;
procedure TTypeDefList.CreateConainer(TypeId: Integer; result: TGenericTypeContainer);
var
I: Integer;
R: TTypeDefRec;
begin
for I := 0 to Count - 1 do
begin
R := Records[I];
if not R.IsGeneric then
continue;
if R.TypeId <> TypeId then
continue;
if R.IsMethodImplementation then
result.MethodList.Add(R.Definition)
else
result.Definition := R.Definition;
end;
end;
procedure TTypeDefList.GenPascalUnits;
function GenUnit(TypeModuleRec: TTypeModuleRec): TStringList;
var
I, J, K, L: Integer;
RI, RL: TTypeExpRec;
RJ: TTypeDefRec;
RK: TTypeExtRec;
S, S1, Q, ModuleName: String;
begin
TypeModuleRec.Success := false;
ModuleName := TypeModuleRec.ModuleName;
result := TStringList.Create;
result.Add('unit ' + GetExtraPascalUnitName(ModuleName) + ';');
result.Add('interface');
if TypeModuleRec.UsingList.Count > 0 then
begin
result.Add('uses ');
for I := 0 to TypeModuleRec.UsingList.Count - 1 do
begin
S := TypeModuleRec.UsingList[I];
if I = TypeModuleRec.UsingList.Count - 1 then
S := S + ';'
else
S := S + ',';
result.Add(S);
end;
end;
result.Add('type');
for I := 0 to TypeExpList.Count - 1 do
begin
RI := TypeExpList[I];
if IndexOf(RI.Name, RI.ParamList, true) >= 0 then
continue;
for J:= 0 to Count - 1 do
begin
RJ := Records[J];
if not StrEql(ModuleName, RJ.ModuleName) then
continue;
if Expansions.IndexOf(I, J) = -1 then
TryExpansion(RI.Name, PASCAL_LANGUAGE, result, TypeModuleRec.Success, I, J);
end;
end;
for J := 0 to Count - 1 do
begin
RJ := Records[J];
if RJ.LangId = PASCAL_LANGUAGE then
if RJ.IsGeneric and (RJ.ParamList.Count = 0) then
if not RJ.IsMethodImplementation then
begin
if RJ.TypeExtList.Count = 0 then
RaiseError(errInternalError, []);
S := RJ.Definition;
S1 := Copy(S, 1, Length(S) - 4);
for K := 0 to RJ.TypeExtList.Count - 1 do
begin
RK := RJ.TypeExtList[K];
for L := 0 to TypeExpList.Count - 1 do
begin
RL := TypeExpList[L];
if RK.ParamList.Count = RL.ParamList.Count then
if StrEql(RK.Name, RL.Name) then
begin
Q := Substitute(RK.Extension, RK.ParamList, RL.ParamList);
Q := EXTRA_KEYWORD + ' ' + Q;
S1 := S1 + Q + #13#10;
end;
end;
end;
S := S1 + 'end;';
result.Add(S);
TypeModuleRec.Success := true;
end;
end;
result.Add('implementation');
for I := 0 to TypeExpList.Count - 1 do
begin
RI := TypeExpList[I];
if IndexOf(RI.Name, RI.ParamList, true) >= 0 then
continue;
for J:= 0 to Count - 1 do
if Expansions.IndexOf(I, J) = -1 then
begin
RJ := Records[J];
if RJ.IsExtra then
continue;
if not RJ.IsGeneric then
continue;
if RJ.LangId = PASCAL_LANGUAGE then
if RJ.IsMethodImplementation then
if RI.ParamList.Count = RJ.ParamList.Count then
if StrEql(RI.Name, RJ.Name) then
begin
TypeModuleRec.Success := true;
S := RJ.Substitute(RI);
result.Add(S);
for K := 0 to RJ.TypeExtList.Count - 1 do
begin
RK := RJ.TypeExtList[K];
for L := 0 to TypeExpList.Count - 1 do
begin
RL := TypeExpList[L];
if RK.ParamList.Count = RL.ParamList.Count then
if StrEql(RK.Name, RL.Name) then
begin
S := Substitute(RK.Extension, RJ.ParamList, RI.ParamList);
S := Substitute(S, RK.ParamList, RL.ParamList);
result.Add(S);
end;
end;
end;
Expansions.Add(I, J);
end;
end;
end;
for J := 0 to Count - 1 do
begin
RJ := Records[J];
if RJ.LangId = PASCAL_LANGUAGE then
if RJ.IsGeneric and (RJ.ParamList.Count = 0) then
if RJ.IsMethodImplementation then
begin
TypeModuleRec.Success := true;
S := RJ.Definition;
result.Add(S);
for K := 0 to RJ.TypeExtList.Count - 1 do
begin
RK := RJ.TypeExtList[K];
for L := 0 to TypeExpList.Count - 1 do
begin
RL := TypeExpList[L];
if RK.ParamList.Count = RL.ParamList.Count then
if StrEql(RK.Name, RL.Name) then
begin
S := RK.Extension;
S := Substitute(S, RK.ParamList, RL.ParamList);
result.Add(S);
end;
end;
end;
end;
end;
result.Add('end.');
if IsDump then
result.SaveToFile(DUMP_PATH + GetExtraPascalUnitName(ModuleName) + '.txt');
end; // GenUnit
var
I: Integer;
temp: TStringList;
begin
for I := 0 to TypeModuleList.Count - 1 do
if TypeModuleList[I].LangId = PASCAL_LANGUAGE then
begin
temp := GenUnit(TypeModuleList[I]);
TypeModuleList[I].Source := temp.Text;
temp.Free;
end;
end;
procedure TTypeDefList.GenBasicUnits;
function GenUnit(TypeModuleRec: TTypeModuleRec): TStringList;
var
I, J: Integer;
RI: TTypeExpRec;
S, ModuleName: String;
begin
TypeModuleRec.Success := false;
ModuleName := TypeModuleRec.ModuleName;
result := TStringList.Create;
result.Add('Module ' + GetExtraBasicUnitName(ModuleName));
if TypeModuleRec.UsingList.Count > 0 then
begin
S := 'Imports ';
for I := 0 to TypeModuleRec.UsingList.Count - 1 do
begin
S := S + TypeModuleRec.UsingList[I];
if I < TypeModuleRec.UsingList.Count - 1 then
S := S + ',';
end;
result.Add(S);
end;
for I := 0 to TypeExpList.Count - 1 do
begin
RI := TypeExpList[I];
if IndexOf(RI.Name, RI.ParamList, true) >= 0 then
continue;
for J:= 0 to Count - 1 do
if Expansions.IndexOf(I, J) = -1 then
TryExpansion(RI.Name, BASIC_LANGUAGE, result, TypeModuleRec.Success, I, J);
end;
result.Add('End Module');
if IsDump then
result.SaveToFile(DUMP_PATH + GetExtraBasicUnitName(ModuleName) + '.txt');
end;
var
I: Integer;
temp: TStringList;
begin
for I := 0 to TypeModuleList.Count - 1 do
if TypeModuleList[I].LangId = BASIC_LANGUAGE then
begin
temp := GenUnit(TypeModuleList[I]);
TypeModuleList[I].Source := temp.Text;
temp.Free;
end;
end;
procedure TTypeDefList.GenJavaUnits;
function GenUnit(TypeModuleRec: TTypeModuleRec): TStringList;
var
I, J: Integer;
RI: TTypeExpRec;
ModuleName: String;
begin
TypeModuleRec.Success := false;
ModuleName := TypeModuleRec.ModuleName;
result := TStringList.Create;
result.Add('package ' + GetExtraJavaUnitName(ModuleName) + ';');
for I := 0 to TypeExpList.Count - 1 do
begin
RI := TypeExpList[I];
if IndexOf(RI.Name, RI.ParamList, true) >= 0 then
continue;
for J:= 0 to Count - 1 do
if Expansions.IndexOf(I, J) = -1 then
TryExpansion(RI.Name, JAVA_LANGUAGE, result, TypeModuleRec.Success, I, J);
end;
if IsDump then
result.SaveToFile(DUMP_PATH + GetExtraJavaUnitName(ModuleName) + '.txt');
end;
var
I: Integer;
temp: TStringList;
begin
for I := 0 to TypeModuleList.Count - 1 do
if TypeModuleList[I].LangId = BASIC_LANGUAGE then
begin
temp := GenUnit(TypeModuleList[I]);
TypeModuleList[I].Source := temp.Text;
temp.Free;
end;
end;
// TTypeParams -----------------------------------------------------------------
procedure TTypeParams.AssTo(L: TTypeParams);
var
I: Integer;
S: String;
TR: TTypeRestrictionRec;
begin
L.Clear;
for I := 0 to Count - 1 do
begin
S := Self[I];
TR := TTypeRestrictionRec(Objects[I]);
if TR = nil then
L.Add(S)
else
L.AddObject(S, TR.Clone);
end;
end;
// TTypeParamsHistory ----------------------------------------------------------
function TTypeParamsHistory.GetRecord(I: Integer): TTypeParams;
begin
result := TTypeParams(L[I]);
end;
function TTypeParamsHistory.Add(const Value: TTypeParams): TTypeParams;
begin
result := TTypeParams.Create;
Value.AssTo(result);
L.Add(result);
end;
// TTypeModuleRec -------------------------------------------------------------
constructor TTypeModuleRec.Create;
begin
inherited;
UsingList := TStringList.Create;
end;
destructor TTypeModuleRec.Destroy;
begin
UsingList.Free;
inherited;
end;
// TTypeModuleList -------------------------------------------------------------
function TTypeModuleList.GetRecord(I: Integer): TTypeModuleRec;
begin
result := TTypeModuleRec(L[I]);
end;
function TTypeModuleList.IndexOf(const ModuleName: String): Integer;
var
I: Integer;
begin
result := -1;
for I := 0 to Count - 1 do
if StrEql(ModuleName, Records[I].ModuleName) then
begin
result := I;
Exit;
end;
end;
function TTypeModuleList.AddModule(const ModuleName: String; LangId: Integer): TTypeModuleRec;
begin
result := TTypeModuleRec.Create;
result.ModuleName := ModuleName;
result.LangId := LangId;
L.Add(result);
end;
// TGenericTypeContainer ------------------------------------------------------
constructor TGenericTypeContainer.Create;
begin
inherited;
MethodList := TStringList.Create;
end;
destructor TGenericTypeContainer.Destroy;
begin
MethodList.Free;
inherited;
end;
procedure TGenericTypeContainer.SaveToStream(S: TStream);
var
B: Byte;
begin
if not GENERICS_ALLOWED then
Exit;
if Definition <> '' then
B := 1
else
B := 0;
S.Write(B, SizeOf(B));
if B = 1 then
begin
SaveStringToStream(Definition, S);
SaveStringListToStream(MethodList, S);
end;
end;
procedure TGenericTypeContainer.LoadFromStream(S: TStream);
var
B: Byte;
begin
if not GENERICS_ALLOWED then
Exit;
S.Read(B, SizeOf(B));
if B = 1 then
begin
Definition := LoadStringFromStream(S);
LoadStringListFromStream(MethodList, S);
end;
end;
end.