2009-06-26 69 views
9

我使用RemObjects(出色)和SynEdit編輯器中的PascalScript創建了一個內置腳本引擎。使用PascalScript提供的IDE示例和SynEdit中的IDE示例幾乎完成了 - 但是 - 我看不出如何詢問PascalScript編號的源代碼行是否爲「可執行」。 (然後我可以用'Delphi藍點'來標記SynEdit的排水溝)。我想我可能需要對ROPS輸出進行拆解?使用Pascal腳本和SynEdit製作IDE

任何PascalScript專家在這裏?謝謝。布萊恩。

+0

這看起來像一個有趣的項目。你有一個網站嗎?一旦你得到它的工作,你會使源代碼可用嗎? – 2009-06-26 22:16:24

回答

9

看看Inno Setup的源代碼。它確實在SynEdit陰影區域中顯示了一個可執行代碼行的小圓點,灰色表示可執行但尚未執行的行,綠色表示已被至少觸及一次的行。

此代碼可在CompForm.pas中找到,請查找TLineState類型。信息設置在編譯器回調的iscbNotifySuccess狀態中,您可以在IDE中執行相同的操作。您可能需要修改代碼以處理多個源文件,因爲Inno Setup編譯器僅處理單個源文件中的代碼片段。

在Pascal Script源代碼中,您應該看看TPSCustomDebugExec.TranslatePositionEx()方法 - 它也會返回源文件的名稱。

1

我不知道它是如何做到的,但PascalScript包(可在\ samples \ debug下找到)中的IDE項目能夠提供Step Into和Step Over(F7和F8)功能,因此在邏輯上它必須有一些方法將PS字節碼與腳本代碼行相關聯。嘗試檢查該項目,看看它是如何做到的。作爲獎勵,它也使用SynEdit,所以這些想法很容易適應你自己的系統。

+0

感謝您對梅森的評論。我一直在使用這個例子。 StepInto和StepOver內置於TPSDebugScript類中,並不奇怪,他們通過實際執行代碼來獲得他們的'I'v結束於此新行'。在代碼執行之前,我需要查詢腳本代碼以查找可能的行,這就是讓我失望的一點。 Bri – 2009-06-26 21:17:15

+0

它如何將代碼映射到源代碼行?沒有1:1的關係。考慮「x:= 5;」和「x:= 5 * performCalculation(y,z + x);」兩者都是一條線,但第二條包含更多的操作。必須有某種元數據與用來執行映射的字節碼混合在一起。 – 2009-06-26 21:26:28

0

我知道這是一個老問題,但我一直在做同樣的事情,上面的建議並沒有真正的幫助。例如Inno setup不使用Synedit,它使用scintilla編輯器。

此外,TPSCustomDebugExec.TranslatePositionEx()與所需內容相反,它從運行時代碼位置提供源代碼行號。

經過一段時間後,我得出結論,最簡單的方法是添加一個函數到Pascalscript代碼。

將新方法添加到uPSdebugger單元中的TPSCustomDebugExec類中。

function TPSCustomDebugExec.HasCode(Filename:string; LineNo:integer):boolean; 
var i,j:integer; fi:PFunctionInfo; pt:TIfList; r:PPositionData; 
begin 
    result:=false; 
    for i := 0 to FDebugDataForProcs.Count -1 do 
    begin 
    fi := FDebugDataForProcs[i]; 
    pt := fi^.FPositionTable; 
    for j := 0 to pt.Count -1 do 
    begin 
     r:=pt[j]; 
     result:= SameText(r^.FileName,Filename) and (r^.Row=LineNo); 
     if result then exit 
    end; 
    end; 
end; 

,並在主編輯器狀漆陰溝回調如下

procedure Teditor.PaintGutterGlyphs(ACanvas:TCanvas; AClip:TRect; 
    FirstLine, LastLine: integer); 
var a,b:boolean; LH,LH2,X,Y,ImgIndex:integer; 
begin 
    begin 
    FirstLine := Ed.RowToLine(FirstLine); 
    LastLine := Ed.RowToLine(LastLine); 
    X := 14; 
    LH := Ed.LineHeight; 
    LH2:=(LH-imglGutterGlyphs.Height) div 2; 
    while FirstLine <= LastLine do 
    begin 
     Y := LH2+LH*(Ed.LineToRow(FirstLine)-Ed.TopLine); 
     a:= ce.HasBreakPoint(ce.MainFileName,FirstLine); 
     b:= ce.Exec.HasCode(ce.MainFileName,FirstLine); 
     if Factiveline=FirstLine then 
     begin 
     if a then 
      ImgIndex := 2 //Blue arrow+red dot (breakpoint and execution point) 
     else 
      ImgIndex := 1; //Blue arrow (current line execution point) 
     end 
     else 
     if b then 
     begin 
      if a then 
      ImgIndex := 3 //Valid Breakpoint marker 
      else 
      ImgIndex := 0; //blue dot (has code) 
     end 
     else 
     begin 
      if a then 
      ImgIndex := 4 //Invalid breakpoint (No code on this line) 
      else 
      ImgIndex := -1; //Empty (No code for line) 
     end; 
     if ImgIndex >= 0 then 
     imglGutterGlyphs.Draw(ACanvas, X,Y,ImgIndex); 
     Inc(FirstLine); 
    end; 
    end; 
end; 

行號,代碼點,斷點,書籤和執行點看Synedit如下

形象

enter image description here