Delphi XE2: Off por 7-20 linhas no depurador e números de linha de erro do compilador também desligado pela mesma quantidade

Eu estou tendo um problema com um grande código Delphi onde eu trabalho onde como um efeito colateral de portar do Delphi 2007 para o XE2, agora encontramos os seguintes problemas estranhos, relacionados:

Você não pode definir pontos de interrupção ou um único passo através do código, mesmo na compilação de depuração, porque a numeração de linhas é toda confusa, apenas em algumas das unidades.

Introduzir um erro de sintaxe deliberadamente na linha 2010 fará com que o cursor se concentre na linha 2020, mais ou menos 3 ou 4 linhas, algo assim:

.

 procedure Correct;
 begin
    DoSomething; // syntax error reported HERE but the real error is below.
    // more stuff here.
 end;

 procedure OllKorrect;  
 begin
        ThisLineIsFine();
        __VARIABLE_NOT_DEFINED__ := 1; // intentional error
 end

Espero que alguém tenha visto isso antes. Os elementos do problema podem incluir:

O código contém muitas diretivas de compilador estranhas como {$ REALCOMPATIBILITY ON} e {$ H -} / {$ H +} diretivas, milhares de diretivas {$ H +} / {$ H-} no código.

Em segundo lugar, o código usa muitas diretivas {$ I INCLUDE}, e eu suspeito que incluir arquivos pode atrapalhar diretamente a numeração de linhas do compilador.

Eu sou incapaz de dizer com certeza, mas eu suspeito que todos esses antigos "fazer funcionar como turbo pascal para DOS" interruptores de compilador são a razão por trás disso. Eu gostaria de saber se alguém sabe alguma coisa sobre isso com certeza. Isso só acontece em alguns lugares no código, e com um projeto que tem mais de 500 unidades, algumas das quais atingem 10K / 20KLOC de tamanho, é definitivamente frustrante. O que eu posso dizer é que não são apenas as unidades que têm as diretivas {$ I include.inc} que fazem bagunça, e que muitas unidades que contêm muitas diretivas de {$ H -} / {$ H +} ou {$ REALCOMPATIBILITY} não tem esse problema. Se eu pudesse ver o que as unidades que se comportam mal têm em comum, eu poderia descobrir isso.

Atualização: A questão da terminação de linha faz sentido. Eu corri este código que detectou problemas. O código de correção está comentado porque, se você descompactá-lo e apagar todo o código-fonte, o problema é seu. Ele está carregando um arquivo não-unicode em um TStringList unicode e salvando-o novamente. Tudo bem no meu mundo porque é tudo versão controlada e backup. Sua milhagem pode variar.

program linefeedsProject1;

{$APPTYPE CONSOLE}

uses
  IOUtils,
  Classes,
  Types,
  SysUtils;


  var
    broken,notBroken:Integer;

  function fix(filename:String):Boolean;
  var
    sl:TStringList;
  begin
    sl := TStringList.Create;
    try
    sl.LoadFromFile(filename);
    //TODO:Change file extensions.
    sl.SaveToFile(filename);
    finally
      sl.Free;
    end;
  end;

  function scan(filename:String):Boolean;
  var
  crFlag:Boolean;
  lfFlag:Boolean;
  missingCr:Integer;
  missingLf:Integer;
   f:TFileStream;
   buf:Array[0..1024] of AnsiChar;
   n:Integer;
   procedure scanChars;
   var
    i:Integer;
   begin
     for i := 0 to n-1 do
     begin
       if buf[i]=#13 then
       begin
          crFlag := true;
          lfFlag := false;
       end
       else if buf[i]=#10 then
       begin
           if not crFlag then
            inc(missingCr);
          lfFlag := true;
          crFlag := false;
       end
       else begin
         if (crFlag) then
          inc(missingLf);
         crFlag := false;
         lfFlag := false;
       end;
     end;
   end;
  begin
   result := false;
   crFlag := false;
   lfFlag := false;
   missingCr := 0;
   missingLf := 0;
    f := TFileStream.Create(filename, fmOpenRead);
    try
      while f.Position< f.Size do
      begin
        n := f.Read(buf[0],1024);
        scanChars;
      end;

     if (missingCr>0) or (missingLf>0) then
     begin
          WriteLn('  ', filename);
          Inc(broken);
          result := true;
     end
     else
     begin
        Inc(notBroken);
     end
    finally
      f.Free;
    end;

  end;
var
 files:TStringDynArray;
 afile:String;
 begin
  try
  broken := 0;
  notBroken := 0;
    files := TDirectory.GetFiles('C:\dev\abackupcopyofyoursourcecode',  '*.pas',
    TSearchOption.soTopDirectoryOnly );
    // tried TSearchOption.soAllDirectories and it exploded. not recommended.

    for afile in files do
    begin
       if scan(afile) then
       begin
           // fix(afile); // uncomment at your own risk and only on a backup copy of your code.
       end;

    end;


    WriteLn('Broken ', broken);
    WriteLn('not broken ',notBroken);

   // readln;

     except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Atualização 2: Se você quiser um scanner / fixador para este problema, você pode baixar o meu (com a fonte) aqui. Link é o Google Drive. Você pode ver o código-fonte do link, mas clique no menu suspenso "Arquivo" (parte da interface de usuário da web do Google Drive) e clique em "Download" para baixá-lo.

questionAnswers(2)

yourAnswerToTheQuestion