Delphi XE2: Aus um 7-20 Zeilen in Debugger- und Compilerfehlerzeilennummern ebenfalls um den gleichen Betrag

Ich habe ein Problem mit einer großen Delphi-Codebasis, in der ich arbeite. Als Nebeneffekt der Portierung von Delphi 2007 auf XE2 treten jetzt die folgenden seltsamen, verwandten Probleme auf:

Sie können auch im Debug-Build keine Haltepunkte oder Code-Einzelschritte festlegen, da die Zeilennummerierung nur in einigen Einheiten fehlerhaft ist.

Das absichtliche Einfügen eines Syntaxfehlers in Zeile 2010 bewirkt, dass sich der Cursor auf Zeile 2020 fokussiert, 3 oder 4 Zeilen gibt oder nimmt.

.

 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

Ich hoffe jemand hat das schon mal gesehen. Zu den Elementen des Problems können gehören:

Der Code enthält viele ungerade Compiler-Direktiven wie {$ REALCOMPATIBILITY ON} und {$ H -} / {$ H +} Direktiven, Tausende von {$ H +} / {$ H-} Direktiven im Code.

Zweitens verwendet der Code viele Anweisungen {$ I INCLUDE}, und ich vermute, dass Include-Dateien die Zeilennummerierung des Compilers direkt durcheinander bringen könnten.

Ich kann es nicht mit Sicherheit sagen, aber ich vermute, dass all diese alten Compiler-Schalter der Grund dafür sind, dass "es wie Turbo Pascal für DOS funktioniert". Ich würde gerne wissen, ob jemand etwas darüber sicher weiß. Es kommt nur an einigen Stellen im Code vor und bei einem Projekt mit über 500 Einheiten, von denen einige eine Größe von 10 K / 20 K LOC erreichen, ist es definitiv frustrierend. Was ich sagen kann ist, dass es nicht nur Einheiten gibt, die Direktiven {$ I include.inc} haben, die durcheinander bringen, und dass viele Einheiten, die viele Direktiven {$ H -} / {$ H +} oder {$ REALCOMPATIBILITY} enthalten, dies tun habe dieses problem nicht. Wenn ich sehen könnte, was die Einheiten, die sich schlecht benehmen, gemeinsam haben, könnte ich das herausfinden.

Update: Das Problem mit der Leitungsbeendigung ist sinnvoll. Ich habe diesen Code ausgeführt, der Probleme festgestellt hat. Der Fixcode ist auskommentiert, da dies Ihr Problem ist, wenn Sie ihn auskommentieren und Ihren gesamten Quellcode löschen. Es lädt eine Nicht-Unicode-Datei in eine Unicode-TStringList und speichert sie wieder ab. In meiner Welt ist das in Ordnung, da alle Versionen kontrolliert und gesichert werden. Ihr Kilometerstand kann variieren.

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.

Update 2: Wenn Sie einen Scanner / Fixer für dieses Problem benötigen, können Sie meinen (mit Quelle) hier herunterladen. Link ist Google Drive. Sie können den Quellcode über den Link anzeigen, aber auf das Pulldown-Menü "Datei" (Teil der Google Drive-Webbenutzeroberfläche) klicken und dann auf "Herunterladen" klicken, um ihn herunterzuladen.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage