Adding AccessSpecifiers via RTTI

Question: “How do I add support for an Indexed property to RAP?”

Answer:  A property such as TStrings.Values, is known as an Access Specifier. If you do a GREP search in the RBuilder source directory, you will find numerous references to AccessSpecifierToRec (see the RAP help for TraRTTI.AccessSpecifierToRec).

AccessSpecifiers are an odd hybrid of property and method, so they require a little bit of the effort of both. Basically, the process is this:

In TraRTTI.CallMethod (here it acts like a method), we get or set values in the aParams parameter. For instance, for TStrings.Values, we do this:

  else if ppEqual(aMethodName, 'Values') then
    begin
      if aGet then
        begin
          aParams.GetParamValue(0, lsName);
          lString := lList.Values[lsName];
          aParams.SetParamValue(1, lString);
        end
      else
        begin
          aParams.GetParamValue(0, lsName);
          aParams.GetParamValue(1, lString);
          lList.Values[lsName] := lString;
        end;
    end

In TraRTTI.GetParams, we treat the AccessSpecifier as a method again, adding two parameters to Result. One for the index and one for the result. Again, with TStrings.Values:

else if ppEqual(aMethodName, 'Values') then
    begin
      Result := TraParamList.Create;
      Result.AddParam('Name', daString, nil, '', False, False);
      Result.AddParam('Result', daString, nil, '', False, False);
    end

In TraRTTI.GetPropList, add the property as a property:

aPropList.AddProp('Values');

In TraRTTI.GetPropRec we use the AccessSpecifierToRec method:

 else if ppEqual(aPropName, 'Values') then
    AccessSpecifierToRec(aPropName, aPropRec)