Skip to content

Commit 87fa7d4

Browse files
committed
Fixed memory leak with circular IMetaType references
1 parent 2bc960c commit 87fa7d4

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

Source/OpenApiGen.CustomAnalyzer.pas

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,12 @@ function TOpenApiCustomAnalyzer.MetaTypeFromObject(const Name: string; Schema: T
245245
if FObjectTypes.TryGetValue(TypeName, Result) then
246246
Exit;
247247

248+
248249
ObjType := TObjectMetaType.Create(TypeName);
249250
Result := ObjType;
250251
FObjectTypes.Add(TypeName, Result);
251252
ObjType.SetDescription(Schema.Description);
253+
252254
for SchemaProp in Schema.Properties do
253255
begin
254256
MetaProp := TMetaProperty.Create;
@@ -265,12 +267,16 @@ function TOpenApiCustomAnalyzer.MetaTypeFromObject(const Name: string; Schema: T
265267
MetaProp.PropType := MetaTypeFromSchema(SchemaProp.Value, Name + PropName, TListType.ltList);
266268
if Options.XDataService and not MetaProp.Required and not MetaProp.PropType.IsManaged then
267269
MetaProp.PropType := TNullableMetaType.Create(MetaProp.PropType);
270+
271+
// PropType is unsafe to avoid circular references so add it to MetaClient for reference counting.
272+
MetaClient.AddReference(MetaProp.PropType);
268273
end;
269274
end;
270275

271276
function TOpenApiCustomAnalyzer.MetaTypeFromReference(RefSchema: TReferenceSchema; const DefaultTypeName: string;
272277
ListType: TListType): IMetaType;
273278
begin
279+
Result := nil;
274280
end;
275281

276282
function TOpenApiCustomAnalyzer.MetaTypeFromSchema(Schema: TJsonSchema; const DefaultTypeName: string;

Source/OpenApiGen.Metadata.pas

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ TMetaProperty = class
109109
private
110110
FFieldName: string;
111111
FPropName: string;
112-
FPropType: IMetaType;
112+
[Weak] FPropType: IMetaType;
113113
FRestName: string;
114114
FRequired: Boolean;
115115
FDescription: string;
@@ -231,10 +231,12 @@ TMetaClient = class
231231
FClientClass: string;
232232
FConfigClass: string;
233233
FBaseUrl: string;
234+
FReferences: TList<IMetaType>;
234235
public
235236
constructor Create;
236237
destructor Destroy; override;
237238
procedure Clear;
239+
procedure AddReference(AType: IMetaType); // just for memory management
238240
function FindMetaType(const Name: string): IMetaType;
239241
function FindService(const Name: string): TMetaService;
240242
property BaseUrl: string read FBaseUrl write FBaseUrl;
@@ -522,21 +524,29 @@ function TMetaProperty.GetHasValuePropName: string;
522524

523525
{ TMetaClient }
524526

527+
procedure TMetaClient.AddReference(AType: IMetaType);
528+
begin
529+
FReferences.Add(AType);
530+
end;
531+
525532
procedure TMetaClient.Clear;
526533
begin
527534
MetaTypes.Clear;
528535
Services.Clear;
536+
FReferences.Clear;
529537
end;
530538

531539
constructor TMetaClient.Create;
532540
begin
533541
inherited Create;
534542
FMetaTypes := TList<IMetaType>.Create;
535543
FServices := TObjectList<TMetaService>.Create;
544+
FReferences := TList<IMetaType>.Create;
536545
end;
537546

538547
destructor TMetaClient.Destroy;
539548
begin
549+
FReferences.Free;
540550
FServices.Free;
541551
FMetaTypes.Free;
542552
inherited;

0 commit comments

Comments
 (0)