I wonder if I have found an Embarcadero compiler bug ...
The problem looks like it is related to generics.
Here is my source code
unit u_DateCount;
interface
uses
  SysUtils,
  u_JavaScriptable
  ;
type
  TDateCount = class (TJavaScriptable)
    strict private
    public
      NoOfSamples : Integer;
      TheDate : TDate;
      function ToString():String; override;
  end;
implementation
function TDateCount.ToString():String;
var
    myYear, myMonth, myDay : Word;
begin
    DecodeDate(TheDate, myYear, myMonth, myDay);
    Result := Format('[new Date(%d, %d ,0), %d]', [myYear, myMonth, NoOfSamples]);
end;
end.
unit u_Javascriptable;
interface
type
  TJavaScriptable = class
    strict private
    public
      function ToString:String; override;
  end;
implementation
function TJavaScriptable.ToString:String;
begin
    Result := '';
end;
end.
unit u_LineChart;
interface
uses
  System.IOUtils,
  SysUtils,
  System.Generics.Collections,
  u_JavaScriptable
  ;
type
  TLineChart<RecordType : TJavaScriptable> = class
    strict private
      Template : String;
      function ConvertRecordsToString():String;
    public
      Records : TList<RecordType>;
      function ToString():String;
      constructor Create(templatePath : String);
      destructor Destroy(); override;
  end;
implementation
function TLineChart<RecordType>.ConvertRecordsToString():String;
var
    I: Integer;
begin
    //Open brackets
    Result := '[ ';
    //The first record
    if Records.Count > 0 then
    begin
        Result := Result + Records[0].ToString();
    end;
    //Loop over records
    for I := 1 to Records.Count - 1 do
    begin
        Result := Result + ', ' + Records[I].ToString();
    end;
    //Close bracket
    Result := Result + ' ]';
end;
function TLineChart<RecordType>.ToString():String;
begin
    Result := Format(Template, [ConvertRecordsToString()]);
end;
constructor TLineChart<RecordType>.Create(templatePath : String);
begin
    inherited Create();
    Template := TFile.ReadAllText(templatePath);
    Records := TList<RecordType>.Create();
end;
destructor TLineChart<RecordType>.Destroy();
var
    I: Integer;
begin
    if Assigned(Records) then
    begin
        for I := 0 to Records.Count - 1 do
        begin
            Records[I].Destroy();
        end;
        Records.Clear();
        Records.Destroy();
        Records := nil;
    end;
    inherited;
end;
end.
And finally the main program
program Project4;
{$APPTYPE CONSOLE}
{$R *.res}
uses
  System.SysUtils,
  u_Javascriptable in 'u_Javascriptable.pas',
  u_LineChart in 'u_LineChart.pas',
  u_DateCount in 'u_DateCount.pas';
var
   lineChart : TLineChart<TDateCount>;
begin
  lineChart := TLineChart<TDateCount>.Create('linechart.html');
  try
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
The error message I get when I try to compile this is
[dcc32 Fatal Error] Project4.dpr(30): F2084 Internal Error: AV097530AC-R00000014-0
Usually when I see an error message similar to this, I can fix it by closing the embarcadero IDE and restarting it. However this did not seem to work this time.
The problem is in the implementation of TLineChart<RecordType>.Destroy().
Change Records[I].Destroy(); to Records[I].Free(); and it works.
Or you just do it correct and use TObjectList<RecordType>.Create; in the constructor which takes care of destroying all elements in it when destroying the list.
Never call Destroy directly. Use Free. While it should not result in a compiler error it is wrong anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With