tags:

views:

152

answers:

3

Hi,

I have a problem with the background compiler in Delphi7: in my project there is a single line of code that causes the background compiler to stop with an error message so that no CodeCompletion is possible. The normal compiler and the syntax check have no problem with this code and the resulting application is correct.

My question is if there is any way to skip this codeline when the background compilation is performed (e.g. compiler directive).

Example code to reproduce the error:

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

This code is placed in a unit "Error.pas" which is used in the main unit. If you try to call CodeCompletion in the main-unit, it stops with the message "Error.pas could not be compiled" (real message is in german).

Interestingly the error only occurs until the project is compiled or syntax check is performed for the first time. After compilation the CodeCompletion is working and Delphi has to be restarted to reproduce the error.

Update: Adding an empty Assembler block with an end label is a solution for the problem. Here is the changed example code that doesn't stop the background compiler:

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

Many thanks,

Christian

+2  A: 

Looks like the background compilation doesn't know what to do with the late binding. Do you know which COM type library is used to make the call on the object? It would benefit both the compilation and the application's performance if you could export and use the pascal-wrapper unit based on the type library. (See Import Type Library option in the main menu)

Stijn Sanders
Thanks for the reply. The application is used for Word automation. The late bindung alone seems to be no problem. For example you can use function names like "v.Foo" that will cause no problems in the background compilation, although no function with this name exists.I think the combination with the Delphi keyword "End" is the problem in this special case.I think that using early binding with a wrapper class is the best idea to solve the problem, when there is no way to exclude the source from background comiplation.
You're right, I didn't notice the called method is a reserved word. That's probably the killer indeed. If you really want late-binding, you *could* call the IDispatch methods to get a method pointer to a name to pass an (empty?) array of parameters to, but that's a long way round ofcourse...
Stijn Sanders
+8  A: 

The background compiler does not do procedure body analysis when parsing to get to the position of the cursor. Instead, it uses simple syntax matching (such as begin/end pairs). If simple syntax matching indicates that the final end in the unit has been met, then it exits early.

This is what's happening with your example. The first End token is not escaped by the late binding logic because it's not being parsed by the real expression compiler, and instead it's being read as the end of the procedure. The second end looks like the end of the unit, and the background compiler never sees any further.

Added: You might try adding an empty asm/end block to this routine. It prevents the kibitz compiler skipping procedure analysis. Graphics.pas has an asm/end block with an @@end label, and the compiler handles asm/end blocks specially because of it.

Barry Kelly
A: 
Marco van de Voort
Sorry, but with this token the code dosn't compile.