2

Delphi DWScriptで使用するIDEを作成していて、簡単なデバッグ可能なスクリプトができました。ここで、ソース内の実行可能行を強調表示します(Delphiソースの左側にある青い点のように)。例/情報を掘り下げる「FindSymbolUsage(suReference)」を呼び出すことができるプログラム「SymbolDictionary」があることがわかります-これにより、「参照されているシンボル」の位置がわかります。割り当てがある行を取得するための「suImplementation」。これにより、ContextMapとSymbolDictionaryの構造と目的が実際に何であるかを理解することでできることに気づきました。スクリプトの実行可能行番号をリストする例はありますか?

私の駆け出しのコードは以下に再現されており、批判的な分析を待っています:-)ありがとう

  TExecutableLines = class( TObject )
    constructor Create;
    destructor  Destroy; override;
  PRIVATE
    FLines : TBits;
    function GetIsExecutable(ALineNumber: integer): boolean;
    procedure SetIsExecutable(ALineNumber: integer; const Value: boolean);
  PUBLIC
    procedure Clear;

    procedure Evaluate( AProgram : IdwsProgram; const AUnitName : string );

    property  IsExecutable[ALineNumber : integer] : boolean
                read GetIsExecutable
                write SetIsExecutable;
  end;





{ TExecutableLines }

procedure TExecutableLines.Clear;
begin
  FLines.Size := 0;
  FLines.Size := 1024;
end;

constructor TExecutableLines.Create;
begin
  inherited;

  FLines := TBits.Create;
end;

destructor TExecutableLines.Destroy;
begin
  FreeAndnil( FLines );
  inherited;
end;

procedure TExecutableLines.Evaluate(AProgram: IdwsProgram; const AUnitName : string);
var
  I : integer;
  Pos : TSymbolPosition;
begin
  Clear;
  For I := 0 to AProgram.SymbolDictionary.Count-1 do
    begin
    Pos := AProgram.SymbolDictionary.FindSymbolPosList(
      AProgram.SymbolDictionary[I].Symbol ).FindUsage( suReference);
    if Pos <> nil then
      If Pos.ScriptPos.IsMainModule then
        IsExecutable[ Pos.ScriptPos.Line ] := True
       else
         if SameText( Pos.UnitName, AUnitName ) then
            IsExecutable[ Pos.ScriptPos.Line ] := True
    end;

end;

function TExecutableLines.GetIsExecutable(ALineNumber: integer): boolean;
begin
  if ALineNumber = 0 then
    raise Exception.Create('Lines numbers are 1..n' );

  if ALineNumber < FLines.Size then
    Result := FLines[ALineNumber]
   else
     Result := False;
end;

procedure TExecutableLines.SetIsExecutable(ALineNumber: integer;
  const Value: boolean);
begin
  if ALineNumber = 0 then
    raise Exception.Create('Lines numbers are 1..n' );

  if ALineNumber >= FLines.Size then
    FLines.Size := ALineNumber+1;
  FLines[ALineNumber] := Value;
end;
4

1 に答える 1

3

TdwsSymbolDictionaryは別の目的を果たします。主に、シンボルが宣言または使用されている場所を把握し、名前変更のリファクタリングなどを容易にします(http://delphitools.info/2011/02/19/spotlight-on-tsymboldictionaryを参照)。 /)。

TdwsSourceContextMapは、ソースコードのどこにコード「ブロック」があるか(クラス宣言が開始および終了する場所、関数実装が開始および終了する場所など)を知るのに役立ちます。どちらも、コード内の位置に「ジャンプ」するのに役立ちます。または、カーソルがシンボルのどこにあるかを知るため。

あなたが求めているのはさらに別の情報です。それはコンパイルされた式に対応する行です。そのためには、コンパイルされたものを確認する必要があります。TExprBase.SubExpr/ SubExprCountは主力製品、またはそれらをラップするユーティリティ関数RecursiveEnumerateSubExprsです。この関数を使用すると、TdwsProgram.ExprおよびTdwsProgram.InitExprから開始して、プログラム内のすべての式を確認できます(IdwsProgramをTdwsProgramにキャストして、これらのプロパティを取得できます)。

これらは、ブレークポイントを持つことができる場所です。

例として、あなたが持っていると仮定します

1.   function Dummy : Integer;
2.   var i : Integer;
3.   begin
4.      while i<10 do begin
5.         Inc(i);
6.         if i>5 then
7.            break;
8.      end;
9.   end;

次に、私が間違っていない場合(これを突然行う):

  • シンボル辞書には、1での「ダミー」の宣言、1と2での「整数」の使用、2での「i」の宣言、4、5、6での「i」の使用がリストされます。

  • コンテキストマップには、関数のブロック、メインブロック、およびwhileループが含まれます。

  • コンパイルされた式の行は2(.InitExpr)と4、5、6、7(.Expr)になります

于 2011-09-02T07:50:34.887 に答える