1

While working on a record type I call TVersion, I utilize class operators. I stumbled across something rather surprising - the operator names are treated as case sensitive.

One of the big things about Delphi is the fact that it's case insensitive. However, class operators seem to defy this rule - at least when it comes to code insight.

Strangely, if both the definition and the implementation use the same case as each other, no errors are raised, regardless of how I actually capitalized them. However, if the definition and implementation are any different in capitalization, it underlines it red and gives me an error:

`TVersion` does not contain a member named 'Implicit'

The same occurs for any class operator I have in this record. In the below code, the first implicit class operator is lower case in the definition, but upper case in the implementation. The rest of them are matching. In the implementation, the Implicit is underlined in red, and I have the mentioned error on the left in the Structure window.

Regardless of any of these errors, everything compiles just fine. I have not seen any difference whether the cases matched or not. Just this annoying editor error. It doesn't even show in the Messages as a warning upon compiling.

Is this a bug? Or should I be concerned about the case sensitivity in these class operators? The documentation, as linked above, does not appear to mention it.

unit JD.Version;

interface

type
  TVersion = record
    Values: array of Integer;
    function Count: Integer;
    class operator implicit(a: TVersion): String;
    class operator Implicit(a: String): TVersion;
    class operator Equal(a, b: TVersion): Boolean;
    class operator LessThan(a, b: TVersion): Boolean;
    class operator GreaterThan(a, b: TVersion): Boolean;
    class operator GreaterThanOrEqual(a, b: TVersion): Boolean;
    class operator LessThanOrEqual(a, b: TVersion): Boolean;
    class operator NotEqual(a, b: TVersion): Boolean;
  end;

implementation

uses
  SysUtils, Math;

{ TVersion }

class operator TVersion.Implicit(a: TVersion): String; //Error: 'TVersion' does not contain a member named 'Implicit'
var
  X: Integer;
begin
  Result:= '';
  for X := 0 to Length(a.Values)-1 do begin
    if X > 0 then Result:= Result + '.';
    Result:= Result + IntToStr(a.Values[X]);
  end;
end;

class operator TVersion.Implicit(a: String): TVersion;
var
  S, T: String;
  I: Integer;
begin
  S:= a + '.';
  SetLength(Result.Values, 0);
  while Length(S) > 0 do begin
    I:= Pos('.', S);
    T:= Copy(S, 1, I-1);
    Delete(S, 1, I);
    SetLength(Result.Values, Length(Result.Values)+1);
    Result.Values[Length(Result.Values)-1]:= StrToIntDef(T, 0);
  end;
end;

class operator TVersion.Equal(a, b: TVersion): Boolean;
var
  la, lb: Integer;
begin
  la := Length(a.Values);
  lb := Length(b.Values);
  if la <> lb then
    Result := False
  else if la = 0 then
    Result := True
  else
    Result := CompareMem(a.Values, b.Values, la * SizeOf(Integer));
end;

class operator TVersion.LessThan(a, b: TVersion): Boolean;
var
  la, lb, i: Integer;
begin
  la := Length(a.Values);
  lb := Length(b.Values);
  for i := 0 to Min(la, lb) - 1 do
    if a.Values[i] < b.Values[i] then   // 1.2.xxx < 1.3.xxx
      Exit(True)
    else if a.Values[i] > b.Values[i] then //1.3.xxx > 1.2.xxx
      Exit(False);
  Result := la < lb;
end;

class operator TVersion.GreaterThan(a, b: TVersion): Boolean;
begin
  Result:= b < a;
end;

class operator TVersion.GreaterThanOrEqual(a, b: TVersion): Boolean;
begin
  Result:= (a > b) or (a = b);
end;

class operator TVersion.LessThanOrEqual(a, b: TVersion): Boolean;
begin
  Result:= (a < b) or (a = b);
end;

class operator TVersion.NotEqual(a, b: TVersion): Boolean;
begin
  Result:= not(a = b);
end;

function TVersion.Count: Integer;
begin
  Result:= Length(Values);
end;

end.

Here's what I'm seeing:

Screenshot - Editor Errors

Jerry Dodge
  • 26,858
  • 31
  • 155
  • 327
  • 2
    This is a bug in Code Insight (or whatever causes the error messages in the Object Inspector). If the code compiles, all is well and that also means that the language is **not** case sensitive, not even WRT class operators. Just the (more limited and different) compiler that does Code Insight. – Rudy Velthuis Jun 11 '17 at 18:37
  • @Rudy Indeed, I figured that far, but I'm curious to know if this is some result of failing to clean up some older language restrictions... such as being case sensitive at some point in the past. Or perhaps this might be a requirement for some platforms...? – Jerry Dodge Jun 11 '17 at 18:38
  • 2
    No, this is not the result of failing to clean up an older language restriction. Code Insight is simply buggy, even in Tokyo, where it has become a little better, but still not faultless. I often get messages that it can't find `System.SysUtils`or `System.Classes` or similar, or that `Exception` does not have a member `Message`, etc.etc. I guess this is just more of the same. – Rudy Velthuis Jun 11 '17 at 18:41
  • @Rudy Yeah, code insight is filled with issues. But I sure found a pattern i this one... – Jerry Dodge Jun 11 '17 at 18:42
  • 6
    Code insight sucks. The code compiles. – David Heffernan Jun 11 '17 at 18:43
  • 1
    There are probably patterns in the other ones as well. Errors do not happen at random, they are just the result of incomplete compilation, because the Code Insight compiler probably cuts some corners. – Rudy Velthuis Jun 11 '17 at 18:44
  • https://stackoverflow.com/a/21484508/62576 – Ken White Jun 12 '17 at 01:01
  • It really does feel like this question should be closed as a duplicate of one the many where the most appropriate answer is: "Yes, Error Insight is buggy. The best solution is to just turn it off." – Disillusioned Jun 12 '17 at 01:18

1 Answers1

4

It is a bug in the Error Insight background compiler. The language itself is case insensitive.

Jerry Dodge
  • 26,858
  • 31
  • 155
  • 327
Victoria
  • 7,822
  • 2
  • 21
  • 44