integrated-application-development / sonar-delphi

Delphi language plugin for SonarQube
GNU Lesser General Public License v3.0
92 stars 13 forks source link

Inconsitent unused const when using const inline #282

Open Valdeirsk8 opened 1 month ago

Valdeirsk8 commented 1 month ago

Prerequisites

SonarDelphi version

1.8.0

SonarQube version

v10.5.1

Issue description

Plugin is raising an erroneous issue when using const inline.

Captura de tela 2024-08-08 163803

Steps to reproduce

const lValue: integer = 0; //<-- unused const SomeMethod(lValue); //

Minimal Delphi code exhibiting the issue

  const ldmServiceOrdemPagamento = TdmServiceOrdemPagamento.Create();
  try
    try
      const lID = pRequest.Params.Field('id').AsString; //sonar plugin is raising an issue here saying unused const
      if ldmServiceOrdemPagamento.Cancelar(lID) then
      begin
        pResponse.Status(THTTPStatus.Accepted);
      end else
      begin
        raise EHorseException.New.Error('Não foi possivel cancelar a ordem de serviço.').Status(THTTPStatus.NotAcceptable);
      end;

    except
      on E: EErrorBadRequest do
      begin
        Log.Error(E);
        raise EHorseException.New.Error(E.Message).Title('Error').status(THTTPStatus.BadRequest);
      end;
      on E: Exception do
      begin
        Log.Error(E);
        raise;
      end;
    end;
  finally
    ldmServiceOrdemPagamento.Free();
  end;
Cirras commented 1 month ago

Hi @Valdeirsk8,

It's unlikely that this is related to the usage of inline const - If you declared it as a normal var, my guess is that you'd still see the false positive.

It's more likely that you're getting a name resolution failure on the call to ldmServiceOrdemPagamento.Cancelar.

I'll need more information:

Valdeirsk8 commented 1 month ago

Hi @Cirras,

what's the signature of that Cancelar method?

  TdmServiceOrdemPagamento = Class(TDmProviderConnection)
  //(...)
  public
    procedure CobrancaPaga(pCobranca: TModelCobranca);
    function GetOrdensPendente(): TJsonArray;
    function Gerar(const pJsonBody: TJsonObject): TJsonObject;
    function Cancelar(const pID: string): Boolean;  //<---- that's the signature
    function Consultar(const pID: string): TJsonObject;
  end;

implementation

where is the Cancelar method declared - straight on TdmServiceOrdemPagamento, or at some other level? Yes, it's declared on TdmServiceOrdemPagamento, it's a datamodule that inherited another datamodule

TdmServiceOrdemPagamento = Class(TDmProviderConnection) and TDmProviderConnection = Class(TDataModule, IPlenusConexaoConfiguracao) implements an Interface

the Cancelar method is declared and implemented on TdmServiceOrdemPagamento


This application is a stateless webserver that need a new database connection on each request, so that's why I use the TDmProviderConnection it's create a new connection to the database, I only need to inherited it and create my querys on the next datamodule.


implementation

uses
  UService.Health,
  UService.OrdemPagamento, //<-- the datamodule is implemented on that unit
  Error.Base,
  Plenus.Log;

class procedure TControllerOrdemPagamento.Delete(pRequest: THorseRequest; pResponse: THorseResponse);
begin
  Log.EnterMethod('TControllerOrdemPagamento.Delete');
  const ldmServiceOrdemPagamento = TdmServiceOrdemPagamento.Create(); //<-- the datamodule is created here
  try
    try
      const lID: string = pRequest.Params.Field('id').AsString;
      if ldmServiceOrdemPagamento.Cancelar(lID) then
      begin
        pResponse.Status(THTTPStatus.Accepted);
      end else
      begin
        raise EHorseException.New.Error('Não foi possivel cancelar a ordem de serviço.').Status(THTTPStatus.NotAcceptable);
      end;

    except
      on E: EErrorBadRequest do
      begin
        Log.Error(E);
        raise EHorseException.New.Error(E.Message).Title('Error').status(THTTPStatus.BadRequest);
      end;
      on E: Exception do
      begin
        Log.Error(E);
        raise;
      end;
    end;
  finally
    ldmServiceOrdemPagamento.Free();
  end;

  Log.ExitMethod('TControllerOrdemPagamento.Delete');
end;
Cirras commented 1 month ago

Hi @Valdeirsk8,

Can you try specifying the type on the ldmServiceOrdemPagamento variable like this?

const ldmServiceOrdemPagamento: TdmServiceOrdemPagamento = TdmServiceOrdemPagamento.Create();

Does the false positive go away when you specify the type of that variable?

If it does, then that would indicate a bug in our type inference around constructor invocations.

Cirras commented 2 weeks ago

Hi @Valdeirsk8,

It's clear to me that something in the name resolution is going wrong around either:

Without more information though, there's not much I can do to diagnose the problem. If I could have a standalone minimal project that reproduces the problem, that would be greatly helpful.