Search code examples
delphidelphi-10.2-tokyo

Delphi code completion fail with anonymous methods


Please create a new FMX application, add a button and a memo to run this example. I have this code:

procedure TForm1.Button1Click(Sender: TObject);
begin
  TTask.Run(procedure
            var
              client: TIdHTTP;
              result: string;
            begin
              client := TIdHTTP.Create(nil);
              try
                try
                  client.ReadTimeout := 4000;
                  client.ConnectTimeout := 4000;
                  result := client.Get('a valid url here just as test');
                  TThread.Synchronize(nil, procedure
                                           begin
                                             Memo1.Lines.Add(result);
                                           end);
                except
                  on E: Exception do
                    begin
                      TThread.Synchronize(nil, procedure
                                           begin
                                             Memo1.Lines.Add(E.Message);
                                           end);
                    end
                end;
              finally
                client.Free;
              end;
            end);
end;

It works as I expect but the problem is in the IDE. If I place the cursor somewhere in the body of the anonymous function, I get the closing of the finally statement automatically.

How can I fix this?


First I am here

enter image description here

Then I press enter and I have this!

enter image description here

If you put the cursor at the beginning and not at the end of the line, you can add new spaces without the completion. How to solve this problem? Well, I have discovered that the issue happens because there is this code:

TThread.Synchronize(nil, procedure
                         begin
                           Memo1.Lines.Add(result);
                         end);

If you remove this code, the issue doens't happen anymore. Is this a bug in the IDE?


Solution

  • Is this a bug in the IDE?

    Yes, this is a bug in the IDE. Your code is syntactically valid.

    How can I fix this?

    The best way to avoid this is to create your code and surround it with try...except... to handle any exception:

      try
        MyClass := TComponent.Create(Self);
        try
    
        finally
          MyClass.Free;
        end;
      except on E: Exception do
      end;
    

    So your code will be:

      TTask.Run(procedure
                var
                  client: TIdHTTP;
                  result: string;
                begin
                  try
                    Client := TIdHTTP.Create(nil);
                    try
                      client.ReadTimeout := 4000;
                      client.ConnectTimeout := 4000;
                      result := client.Get('a valid url here just as test');
                      TThread.Synchronize(nil, procedure
                                               begin
                                                 Memo1.Lines.Add(result);
                                               end);
                    finally
                      Client.Free;
                    end;
                  except on E: Exception do
                    begin
                      TThread.Synchronize(nil, procedure
                                               begin
                                                 Memo1.Lines.Add(E.Message);
                                               end);
                      end;
                  end;
                end;