On 01.07.2019 23:25, Michael Van Canneyt wrote:
I understand. But all depends on how the compiler parses and evaluates this.

Let me put brackets to make it more clear: is

MyTest.StringArray[i]

parsed & evaluated as

(MyTest.StringArray)([(i)])

or as

(MyTest.StringArray[(i)])

In the former case, the compiler cannot know what the result type is of the
first set of brackets in your proposal. In the latter case, it can be OK.

But I simply do not know, someone with more intimate knowledge of the
compiler needs to shed light on this.

I happened to study this part of FPC code back in 2015 when I worked on issue #28820. I can say that FPC directly transfers indexed properties to method calls with the parameters from []-brackets without checking if the property definition exists - and even without checking if the []-brackets are there. That means, in case StringArray is an array property:

MyTest.StringArray[i]

is always evaluated as

MyTest.StringArrayGetter(i)

and never as

(MyTest.StringArray)[i]

the same goes for

MyTest.StringArray -> MyTest.StringArrayGetter()
MyTest.StringArray[] -> MyTest.StringArrayGetter()
MyTest.StringArray['abc'] -> MyTest.StringArrayGetter('abc')
MyTest.StringArray['abc', 123, 3.14] -> MyTest.StringArrayGetter('abc', 123, 3.14)

But you can explicitly add the brackets around MyTest.StringArray - the compiler allows this.

Let me show you some code to prove myself:

program Project1;
{$mode objfpc}
type
  TValue = record A: Integer end;
  TMyClass = class
  private
    function GetValue: string;
    function GetValue(aindex: string): Double;
  public
    property Index[aindex: string]: Double read GetValue;
  end;
{ TMyClass }
function TMyClass.GetValue(aindex: string): Double;
begin
  Writeln('double indexed overload called');
  Result := Length(aindex);
end;
function TMyClass.GetValue: string;
begin
  Writeln('string not-indexed overload called.');
  Result := 'abc';
end;
var
  c: TMyClass;
begin
  c := TMyClass.Create;
  Writeln(c.Index);        // allowed - string overload
  Writeln(c.Index[]);      // allowed - string overload
  Writeln(c.Index[2]);     // not allowed - overload does not exist (comment out to compile the program)
  Writeln(c.Index[][2]);   // allowed - string overload
  Writeln((c.Index)[2]);   // allowed - string overload
  Writeln(c.Index['abc']); // allowed - double overload
  ReadLn;
end.

---

So actually, what you call as "my proposal" is not really a proposal - the whole property overload feature is already present in FPC. But now it's just by accident and with wrong syntax. We only need 2 steps to convert this bug into a feature: 1.) Check the indexed property definition before calling the getter/setter + allow indexed property overloads. 2.) Forbid the empty-[]-brackets-syntax so that "c.Index[]" and "c.Index[][2]" from example above will become invalid.

Ondrej

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to