RomanYankovsky / DelphiAST

Abstract syntax tree builder for Delphi
Mozilla Public License 2.0
271 stars 116 forks source link

procedural types with `of object` are not recorded correctly #245

Open JBontes opened 6 years ago

JBontes commented 6 years ago

The following code does not register the of object part: In addition, because function and procedure are reserved words, they should not be stored in a anName attribute but in a anType attribute instead.

type
  x = procedure of object;
  y:= function(x: integer): integer of object;

Here's the fix:

type
  TAttributeValue = (atAsm, atTrue, atFunction, atProcedure, atOperator, atClassOf, atClass,
    atConst, atConstructor, atDestructor, atEnum, atInterface, atNil, atNumeric,
    atOut, atPointer, atName, atString, atSubRange, atVar, atType{ExplicitType},
    atObject, atSealed, atAbstract, atBegin, atOf_Object{procedure of object});

var
  AttributeValues: array[TAttributeValue] of string;

procedure InitAttributeValues;
var
  value: TAttributeValue;
  AttributeStr: string;
begin
  for value := Low(TAttributeValue) to High(TAttributeValue) do begin
    AttributeStr:= Copy(LowerCase(GetEnumName(TypeInfo(TAttributeValue), Ord(value))), 3);
    AttributeStr:= StringReplace(AttributeStr, '_', ' ', [rfReplaceAll]);
    AttributeValues[value] := AttributeStr;
  end;
end;

procedure TPasSyntaxTreeBuilder.ProceduralDirectiveOf;
var
  Proc: TSyntaxNode;
begin
  //anType is already used for set/enum/subrange/class/record/interface/object.
  //It could be reused for this data, but it's a directive, not a type as such.
  //And it's to close to `object` proper.
  //It should not be a subnode, because only 'of object' is allowed.
  FStack.Peek.Attribute[anKind]:= AttributeValues[atOf_Object];
  inherited;
end;

Part2 of the fix:

procedure TPasSyntaxTreeBuilder.ProceduralType;
begin
  //procedure/function is a reserved word, so it cannot be the same as an identifier.
  FStack.Push(ntType).Attribute[anType]:= Lexer.Token;
  try
    inherited;
  finally
    FStack.Pop;
  end;
end;