Skip to content

Add Delphi 10.2 Tokyo support via dedicated client and tool frame#101

Open
andrevfarias wants to merge 14 commits intointegrated-application-development:masterfrom
andrevfarias:delphi-tokyo-compatibility
Open

Add Delphi 10.2 Tokyo support via dedicated client and tool frame#101
andrevfarias wants to merge 14 commits intointegrated-application-development:masterfrom
andrevfarias:delphi-tokyo-compatibility

Conversation

@andrevfarias
Copy link
Copy Markdown
Contributor

This PR introduces initial compatibility for Delphi 10.2 Tokyo by adding a dedicated client build and a Tokyo-specific tool window implementation. It addresses the request to support older Delphi IDEs, motivated by issue #14.

Summary of changes

  • New Tokyo tool frame:
    • Added DelphiLint.ToolFrame.Tokyo.pas/.dfm, using TListView and TWebBrowser (SHDocVw) instead of newer components that are not available on 10.2.
  • New 10.2 Tokyo client projects:
    • Added client/source/DelphiLintClient250.dpk, DelphiLintClient250.dproj, and group project client/DelphiLintClientProjects250.groupproj.
    • Added test project client/test/DelphiLintClientTest250.dpr/.dproj.
  • Conditional compilation for older IDEs:
    • DelphiLint.Plugin.pas selects DelphiLint.ToolFrame.Tokyo when CompilerVersion < 33.0.
    • DelphiLint.IDEContext.pas uses IOTAIDEThemingServices250 where required.
  • Build and packaging:
    • scripts/build.ps1 updated to support version 250 (Tokyo), map registry version 19.0, and use DCC_UseMSBuildExternally=true to avoid long command-line issues.
  • Minor compatibility tweaks across units (Analyzer, HtmlGen, Server, Settings, etc.) to compile and run on Tokyo.
  • No behavior changes for Alexandria/Athens; newer IDEs continue using the existing frame and WebView2.

Why

  • Many teams still use Delphi 10.2 Tokyo, and the main client relies on components not available there. This PR provides a safe, isolated implementation for Tokyo without impacting newer Delphi versions. See issue #14.

Build notes

  • Use the existing build pipeline with the 250 target (e.g., build.ps1 250).

Impact

  • Adds 10.2 support with a separate UI implementation; maintains current behavior for Delphi 11/12.

Copy link
Copy Markdown
Collaborator

@fourls fourls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @andrevfarias, thank you for the PR! It mostly looks good and I'm happy to accept most of its changes to improve compatibility with older Delphi versions.

I have made some comments. Because I do not have Tokyo installed, I will not be able to test it or ensure any quality guarantees.

Many teams still use Delphi 10.2 Tokyo, and the main client relies on components not available there.

I'm not super comfortable with how specific this change is to 10.2. Many teams still use Delphi 7, XE3, etc, but that doesn't seem like a reason to require a separate tool frame for each of those versions as well. Could we reframe this as a more general "legacy tool frame" instead of something specific to a minor release of the compiler?

Also, the build script should not be updated to build unsupported versions of Delphi. The purpose of the build script is for packaging and release, which won't need to be done for unsupported versions. There's also nothing special about 10.2 that necessitates it being added to the build script, and it implies a guarantee that it will be compatible (which there is not).

The script doesn't do anything fancy, so if you'd like to compile an unsupported version's BPL it can just be compiled in the IDE / via MSBuild / whatever approach is best for your setup. Or by making the changes to the build script locally.


if not TFile.Exists(FLogPath) then begin
FreeAndNil(TFile.Create(FLogPath));
TFile.Create(FLogPath).Free;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of these changes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In older Delphi versions (like Tokyo), passing a constant object to FreeAndNil() as a var parameter triggers the compiler error E2197 Constant object cannot be passed as var parameter. Since this is a local instantiation and we don't strictly need to nil the reference, calling .Free directly solves the issue.

Comment thread client/source/DelphiLint.Handlers.pas Outdated
Hook.Free;
end;
FreeAndNil(FPopupHooks);
FreeAndNil(FPopupHooks); // Remover?
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this comment mean?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just garbage, I've removed it.


function TRuleHtmlGenerator.BuildHtmlPage(BodyHtml: string; BodyClass: string): string;

function GetLegacyScript: string;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Webpack/Babel can polyfill for old IE versions (see client/jslib/webpack.config.js) so there's no need to include it ourselves. Could you identify the IE version you want to support and try configuring webpack to bundle for that version?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TWebBrowser uses an IE7 engine, and even when configuring Webpack / Babel to target that version, the runtime still lacks fundamental features (e.g., Object.defineProperty). These cannot be reliably polyfilled, which leads to script errors at execution time.

Comment thread client/source/DelphiLint.IDEContext.pas Outdated
Comment on lines +362 to +366
{$IF CompilerVersion < 33.0}
(BorlandIDEServices as IOTAIDEThemingServices250).RegisterFormClass(FormClass);
{$ELSE}
(BorlandIDEServices as IOTAIDEThemingServices).RegisterFormClass(FormClass);
{$ENDIF}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to do the ifdef here, just change to 250 if it's a compatibility issue. Newer Delphi versions also have the 250 version.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

begin
LintContext.IDEServices.ApplyTheme(Self);
WindowColor := StyleServices(Self).GetSystemColor(clWindow);
WindowColor := StyleServices.GetSystemColor(clWindow);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this trailing whitespace.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread client/source/DelphiLint.SetupForm.pas Outdated
begin
LintContext.IDEServices.ApplyTheme(Self);
WindowColor := StyleServices(Self).GetSystemColor(clWindow);
WindowColor := StyleServices.GetSystemColor(clWindow);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this trailing whitespace.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please

  • Translate comments to English
  • Remove Tokyo-specific references
  • Include this unit in all DelphiLintClient dprojs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially done.
As DelphiLint.ToolFrame.Tokyo.pas uses the same component names as DelphiLint.ToolFrame.pas, keep both included in the projects causes conflicts from duplicated classes, I've kept only in DelphiLintClient250 project.

Comment thread scripts/build.ps1
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert this change. As stated previously, we will not be officially supporting building for versions of Delphi before Delphi 11, especially not specifically for 10.2.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. I have reverted the changes made to the build script (build.ps1).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of this change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That change was a leftover from local testing and was unnecessary for the scope of this PR. I have already reverted it.

Comment on lines +110 to +112
if (properties.containsKey("sonar.sourceEncoding")) {
return Charset.forName(properties.get("sonar.sourceEncoding"));
} else if (properties.containsKey("sonar.encoding")) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, this seems like a legitimate bug, thanks for picking this up. Could you move this out into a separate commit?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I have split the history and isolated this fix into its own dedicated commit (fix: update charset configuration key for compatibility).

@andrevfarias andrevfarias force-pushed the delphi-tokyo-compatibility branch 2 times, most recently from 03873b8 to 71bd46a Compare April 22, 2026 20:05
- Changed the property key from `sonar.encoding` to `sonar.sourceEncoding`
  to align with updated configuration standards.
- Replaced the for-in loop with an index-based for loop to fix the
  E2197 compiler error: 'Constant object cannot be passed as var
  parameter' on freeAndNil call when compiling in older Delphi versions.
  This change ensures compatibility with legacy Delphi versions.
…ng errors

- Older Delphi versions throw implicit casting error when using implicit
  casting of TArray<string> on function return types.
- This change forces the casting to avoid the implicit casting error.
…g errors

- Older Delphi versions throw the error:
  E2197 Constant object cannot be passed as var parameter
  when a constant object is passed as var parameter.
- When a local var is assigned to nil, it's not necessary to call
  FreeAndNil, .Free is enough.
- Older Delphi versions does not accept direct item access
  via `Json[Index]`. Used `Json.Items[Index]` instead.
- Older Delphi versions doesn't have `TJsonValue.AsType<string>`.
  Used explicit casting to TJsonString instead.
- Use ParseJSONValue from TJSONObject instead of TJSONValue.
@andrevfarias andrevfarias force-pushed the delphi-tokyo-compatibility branch from 71bd46a to e0e8ace Compare April 23, 2026 19:00
…cy compatibility

- Older Delphi versions requires to pass `Self` parameter when
  calling StyleServices.
- Newer Delphi versions also have this overloaded method.
- Introduced the EscapedString function to handle special character
  escaping for older Delphi versions.
- Updated data handling in the server to use EscapedString when
  CompilerVersion is less than 33.0.
- Added new project files for DelphiLintClient250.
- Implemented ToolFrame.Legacy to support legacy Delphi versions while
  maintaining functionality.
- Implemented legacy script handling in HTML generation to ensure
  compatibility with older browsers.
@andrevfarias andrevfarias force-pushed the delphi-tokyo-compatibility branch from e0e8ace to 922dc7f Compare April 23, 2026 20:47
@andrevfarias
Copy link
Copy Markdown
Contributor Author

Hi @fourls, thanks for the feedback!
I have rebased the entire branch and cleaned up the commit history to address all your requests.

Here is a summary of the updates:

  1. Reframed the specific "10.2 Tokyo" implementation into a broader "Legacy" compatibility approach.
  2. Reverted all changes to the build/install scripts (build.ps1 and TEMPLATE_install.ps1).
  3. Isolated the legitimate bug fix (Charset configuration in AnalysisOrchestrator.java) into its own separate commit.
  4. Split the changes into smaller, logical commits to make future reviews and history tracking easier.

Let me know if everything looks good now!

@andrevfarias andrevfarias requested a review from fourls April 23, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants