GExperts: Rename Identifier – recent improvements

The Rename Identifier editor expert has received several improvements that make it smarter and safer. Here’s an overview.

Identifier info display

The rename dialog now shows detailed information about the identifier under the cursor:

  • Kind: variable, constant, type, parameter, field, property, method, or external identifier
  • Type: the declared type (e.g. Integer, TStringList, array of string), including generics like TList<Integer>
  • Scope: where the identifier lives: local in a procedure, member of a class, or unit-level, with interface/implementation distinction for unit-level identifiers

This lets you check that you’re renaming the right thing.

Conflict detection

When you type a new name, Rename Identifier checks in real time (with a 200ms debounce) whether the name already exists as a visible identifier in the same scope. For example, if you’re renaming a local variable and type a name that’s already used by another local variable, a parameter, a class member, or a unit-level identifier, a red warning is shown. The warning is informational only: it doesn’t block the rename, since there are legitimate reasons to introduce shadowing.

Component coordination

Rename Identifier now works together with Rename Components (Shift+F2):

  • Source to DFM: When you rename a component field in the source editor (e.g. Button1), the component is also renamed in the form designer. A warning label reminds you that the DFM will be affected. Renaming the form itself is blocked with a message directing you to the Object Inspector.
  • DFM to Source: When you rename a component via Rename Components in the form designer, source code references are also updated. This is controlled by a new “Also rename source code references” checkbox in the Rename Components configuration (enabled by default).
  • Shared shortcut: Shift+F2 now forwards to Rename Identifier when the code editor is focused, so the same shortcut works in both the form designer and the code editor.

Method parameter fix

When renaming a method parameter, the rename now correctly propagates between the class declaration and the implementation. Previously, only the scope where the cursor was located got renamed, and the other half was missed. For example, renaming AValue in the implementation of TMyClass.SetValue now also renames it in the class declaration, and vice versa.

Implicit Result variable

In Delphi, every function has an implicit Result variable that is never explicitly declared. Previously, placing the cursor on Result and invoking Rename Identifier treated it as a unit-level identifier and would have renamed every Result across the entire unit.

Result is now recognized as an implicit local variable belonging to its enclosing function (or constructor/destructor). The dialog shows it as:

  • Kind: implicit function result
  • Type: the function’s return type

A warning is displayed: ‘Result’ is a compiler-managed implicit variable. Renaming it may cause unexpected behavior.

The implementation correctly handles Delphi’s scoping rules for nested routines:

function Outer: Integer;
  procedure Inner;        // NOT a function, no own Result
  begin
    Result := 1;          // refers to Outer's Result
  end;
  function InnerFunc: string;
  begin
    Result := 'x';        // refers to InnerFunc's Result
  end;
begin
  Result := 42;           // refers to Outer's Result
end;
  • Renaming Result inside Inner (a procedure, not a function) renames it in the enclosing function Outer‘s scope, including Result := 42 in Outer‘s body.
  • Renaming Result inside InnerFunc only affects InnerFunc, because a nested function has its own Result that shadows the outer one.

Tests

The Rename Identifier engine now has 69 unit tests covering local variables, parameters, class members, records, unit-level identifiers, shadowing, nested procedures, forward declarations, class methods, component coordination, identifier info, conflict detection, implicit Result, and various edge cases.

As usual, if you want to try this before the next official release, you can compile your own DLL.

Discussion about this in the corresponding post in the international Delphi Praxis forum.