Recent

Author Topic: CodeTools detection using macros  (Read 852 times)

Khrys

  • Sr. Member
  • ****
  • Posts: 345
CodeTools detection using macros
« on: October 07, 2025, 08:54:12 am »
CodeTools works great for the most part, but some annoying bugs still show up from time to time.
Since upgrading to Lazarus trunk isn't always an option, I wanted to ask: Does CodeTools define any special macros?

For example, in Lazarus 4.0 CodeTools breaks if the first function in the  implementation  section is generic. Currently I'm using this workaround:

Code: Pascal  [Select][+][-]
  1. implementation
  2.  
  3. {$ifopt D+} procedure __CodeTools_Jump_Fix(); begin end; {$endif}
  4.  
  5. generic procedure Foo<T>(): T; {...}

It would be great if I could enclose problematic code in something like  {$ifdef CODETOOLS}  (at least until the underlying issue is fixed & upgrading becomes possible), but  SourceUnit information...Show CodeTools Values  doesn't show anything interesting, so I'm not very optimistic.

Thaddy

  • Hero Member
  • *****
  • Posts: 18356
  • Here stood a man who saw the Elbe and jumped it.
Re: CodeTools detection using macros
« Reply #1 on: October 07, 2025, 09:16:15 am »
I had an idea but removed it.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

cdbc

  • Hero Member
  • *****
  • Posts: 2467
    • http://www.cdbc.dk
Re: CodeTools detection using macros
« Reply #2 on: October 07, 2025, 09:25:55 am »
Hi
I've worked around like this:
Code: Pascal  [Select][+][-]
  1. {-$define coding}
  2. {$ifNdef coding}
  3.   { TBucketFactory }
  4.   TBucketFactory = object    
  5.     { creates and returns an IBucketListxxx depending on the provided type 1..5
  6.       0,1: Data | 2: String | 3: TObject | 4: IInterface | 5: ICorba }
  7.     function FetchBucketList(aBucketType: word;
  8.                              aFreeProc: TDisposeProc = nil;
  9.                              out anIBucketList): boolean;
  10.     { e.g.: bls:= BucketFactory.specialize GetBucketList<IBucketListStr>(nil,BucketCompareKey,100); }
  11.     generic function GetBucketList<T>(aFreeProc: TDisposeProc = nil): T;
  12.   end;
  13.   { factory object that creates an instance of the 5 available BucketLists }
  14.   var BucketFactory: TBucketFactory;
  15. {$endif}
  16.   ...
  17. implementation
  18. {$ifNdef coding}
  19. { TBucketFactory }
  20. generic function TBucketFactory.GetBucketList<T>(aFreeProc: TDisposeProc = nil): T;
  21. var ti: PTypeInfo;
  22. begin
  23.   ti:= TypeInfo(T);
  24.   case IndexStr(ti^.Name,['IBucketListBase','IBucketListData','IBucketListStr','IBucketListObj','IBucketListIntf','IBucketListCorba']) of
  25.     0,1: pointer(Result):= CreBucketListData(aFreeProc); { we don't do base!!! }
  26.     2: pointer(Result):= CreBucketListStr;
  27.     3: pointer(Result):= CreBucketListObj;
  28.     4: pointer(Result):= CreBucketListIntf;
  29.     5: pointer(Result):= CreBucketListCorba;
  30.   end;
  31. end;
  32.  
  33. function TBucketFactory.FetchBucketList(aBucketType: word;
  34.                                         aFreeProc: TDisposeProc = nil;
  35.                                         out anIBucketList): boolean;
  36. begin
  37.   pointer(anIBucketList):= nil; { init }
  38.   if (aBucketType > 5) then exit(false);
  39.   case aBucketType of
  40.     0,1: pointer(anIBucketList):= CreBucketListData(aFreeProc); { we don't do base!!! }
  41.     2: pointer(anIBucketList):= CreBucketListStr;
  42.     3: pointer(anIBucketList):= CreBucketListObj;
  43.     4: pointer(anIBucketList):= CreBucketListIntf;
  44.     5: pointer(anIBucketList):= CreBucketListCorba;
  45.   end;
  46.   Result:= (pointer(anIBucketList) <> nil);
  47. end;
  48. {$endif}
  49.  
I just enable the define when I'm working on it and disable the define if I need it when compiling...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6 -> FPC 3.2.2 -> Lazarus 4.0 up until Jan 2025 from then on it's both above &: KDE6/QT6 -> FPC 3.3.1 -> Lazarus 4.99

Thaddy

  • Hero Member
  • *****
  • Posts: 18356
  • Here stood a man who saw the Elbe and jumped it.
Re: CodeTools detection using macros
« Reply #3 on: October 07, 2025, 05:03:28 pm »
Very intricate way to avoid assert Benny?
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

cdbc

  • Hero Member
  • *****
  • Posts: 2467
    • http://www.cdbc.dk
Re: CodeTools detection using macros
« Reply #4 on: October 07, 2025, 05:09:15 pm »
Hi
Nah, /intricate/ I dunno, but for me it works very stable...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6 -> FPC 3.2.2 -> Lazarus 4.0 up until Jan 2025 from then on it's both above &: KDE6/QT6 -> FPC 3.3.1 -> Lazarus 4.99

Khrys

  • Sr. Member
  • ****
  • Posts: 345
Re: CodeTools detection using macros
« Reply #5 on: October 08, 2025, 07:28:57 am »
I found that  DEBUGINFO  (yes, as a preprocessor symbol/macro, not  {$debuginfo})  is only defined when editing (in debug mode of course), but not when compiling.
Unreliable, but good enough for now  O:-)

PascalDragon

  • Hero Member
  • *****
  • Posts: 6191
  • Compiler Developer
Re: CodeTools detection using macros
« Reply #6 on: October 09, 2025, 09:59:51 pm »
You can use this trick that I used for the Rtti unit before Lazarus was capable of handling generic methods:

Code: Pascal  [Select][+][-]
  1. { Note: since the Lazarus IDE is not yet capable of correctly handling generic
  2.   functions it is best to define a InLazIDE define inside the IDE that disables
  3.   the generic code for CodeTools. To do this do this:
  4.  
  5.   - go to Tools -> Codetools Defines Editor
  6.   - go to Edit -> Insert Node Below -> Define Recurse
  7.   - enter the following values:
  8.       Name: InLazIDE
  9.       Description: Define InLazIDE everywhere
  10.       Variable: InLazIDE
  11.       Value from text: 1
  12. }
  13. {$ifdef InLazIDE}
  14. {$define NoGenericMethods}
  15. {$endif}

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11817
  • Debugger - SynEdit - and more
    • wiki
Re: CodeTools detection using macros
« Reply #7 on: October 12, 2025, 01:05:28 pm »
For example, in Lazarus 4.0 CodeTools breaks if the first function in the  implementation  section is generic. Currently I'm using this workaround:

Code: Pascal  [Select][+][-]
  1. implementation
  2.  
  3. {$ifopt D+} procedure __CodeTools_Jump_Fix(); begin end; {$endif}
  4.  
  5. generic procedure Foo<T>(): T; {...}

I can not get Codetool to fail on the above example (in 4.3 (fixes branch).

Well, as soon as I replace "procedure" with "function" because the former does not have a result type.

Khrys

  • Sr. Member
  • ****
  • Posts: 345
Re: CodeTools detection using macros
« Reply #8 on: October 13, 2025, 06:56:51 am »
Well, as soon as I replace "procedure" with "function" because the former does not have a result type.

:-[
Yes, it should be a function.
I just needed a quick example for my post and didn't check whether that specific issue might've already been fixed in trunk.

 

TinyPortal © 2005-2018