2009-08-10 7 views
4

Delphi7のバックグラウンドコンパイラに問題があります。私のプロジェクトには、バックグラウンドコンパイラがエラーメッセージで停止してCodeCompletionが実行できないコードが1行あります。通常のコンパイラと構文チェックではこのコードに問題はなく、結果のアプリケーションは正しいです。バックグラウンド(キビッツ)コンパイラのソースコードをスキップ

私の質問は、バックグラウンドコンパイルが実行されたときにこのコードラインをスキップする方法があるかどうかです(コンパイラ指令など)。エラーを再現する

例コード:

procedure ProduceKibitzError; 
var 
    v : Variant; 
begin 
    v.End; // This line stops kibitz compiler 
end; 

このコードは、本体に使用される「Error.pas」ユニット内に配置されます。 メインユニットでCodeCompletionを呼び出そうとすると、「Error.pasをコンパイルできませんでした」というメッセージで停止します(実際のメッセージはドイツ語です)。

興味深いことに、このエラーは、プロジェクトがコンパイルされるか、構文チェックが初めて実行されるまで発生します。 コンパイル後、CodeCompletionが機能しており、エラーを再現するためにDelphiを再起動する必要があります。

更新: エンドラベル付きの空のアセンブラブロックを追加することは、問題の解決方法です。

+0

ケア*のように見えますか? –

+0

空のasm/endブロックをこのルーチンに追加してみてください。それはキビッツコンパイラが手続き解析をスキップするのを防ぎます。 Graphics.pasには、@ endラベル付きのasm/endブロックがあり、コンパイラは特別にasm/endブロックを処理します。 –

答えて

10

バックグラウンドコンパイラは、カーソルの位置に到達するために解析するときにプロシージャー本体解析を行いません。代わりに、単純な構文マッチング(例えば、begin/endのペア)を使用します。単純な構文マッチングで、ユニット内の最後のendが満たされたことが示された場合、早期に終了します。

これはあなたの例で起こっていることです。最初のEndトークンは、実際の式コンパイラによって解析されておらず、その代わりにプロシージャの最後として読み込まれているため、レイトバインディングロジックによってエスケープされません。 2番目のendはユニットの終わりのように見え、バックグラウンドコンパイラはこれ以上見ることはありません。

追加:空のasm/endブロックをこのルーチンに追加してみてください。それはキビッツコンパイラが手続き解析をスキップするのを防ぎます。 Graphics.pasには、@ endラベル付きのasm/endブロックがあり、コンパイラは特別にasm/endブロックを処理します。

2

クリスチャン

procedure ProduceKibitzError; 
var 
    v : Variant; 
begin 
    asm 
    @@END: 
    end; 
    v.End; 
end; 

多くのおかげで、バックグラウンドコンパイルが遅くて何をすべきか分かっていないように見える: はここでバックグラウンドコンパイラを停止しない変更のサンプルコードがあります結合。 どのCOMタイプライブラリがオブジェクトの呼び出しに使用されているか知っていますか?タイプ・ライブラリーに基づいてパスカル・ラッパー・ユニットをエクスポートして使用することができれば、コンパイルとアプリケーションのパフォーマンスの両方に役立ちます。 (メインメニューのImport Type Libraryオプションを参照してください)

+1

返事をありがとう。このアプリケーションは、Wordの自動化に使用されます。 遅いバインドンだけで問題はないようです。たとえば、 "v.Foo"のような関数名を使うことができます。この名前は、バックグラウンドコンパイルでは問題にはなりませんが、この名前の関数は存在しません。 この特殊なケースでは、Delphiのキーワード「End」との組み合わせが問題だと思います。 私は、ラッパークラスでアーリーバインディングを使用することは、バックグラウンドの苦闘からソースを除外する方法がないとき、問題を解決するための最良のアイデアだと思います。 – user153642

+0

あなたが正しいです、私は呼び出されたメソッドが予約語であることに気がつかなかった。それはおそらく本当にキラーでしょう。遅延バインディングが本当に必要な場合は、IDispatchメソッドを呼び出して名前へのメソッドポインタを取得して(空の?)配列の配列を渡すことができますが、それは長い道のりです... –

1

&でトークンをエスケープしてみますか?

ので

V。何その*一行のコード*と*にErrorMessageを投稿する&end;

+0

申し訳ありませんが、このトークンでコードはコンパイルされません。 – user153642

+0

これはD2005に追加されました。 .Netのサポートとは何か - 多くの.Netライブラリには、Delphiで予約されたキーワードである名前を持つメソッドがあると思います。 –

+0

いいえ、古いです。 D6マニュアルはすでにそれを言及した。 IDispatchのサポートが付いてきたと思いますが、その理由は同じです。 COMオブジェクトは既に非デルファイ名のメソッドをサポートしています。 –

関連する問題