RomanYankovsky / DelphiAST

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

Class var sections are not properly captured #234

Open JBontes opened 6 years ago

JBontes commented 6 years ago

class var does not register properly.

Here's the fix for class, object, and record respectively:

procedure TPasSyntaxTreeBuilder.ClassField;
var
  Fields, Temp: TSyntaxNode;
  Field, TypeInfo, TypeArgs: TSyntaxNode;
  IsClassVarSection: boolean;
begin
  IsClassVarSection:= FStack.Peek.HasAttribute(anClass);
  Fields := TSyntaxNode.Create(ntFields);
  try
    FStack.Push(Fields);
    try
      inherited;
    finally
      FStack.Pop;
    end;

    TypeInfo := Fields.FindNode(ntType);
    TypeArgs := Fields.FindNode(ntTypeArgs);
    for Field in Fields.ChildNodes do
    begin
      if Field.Typ <> ntName then
        Continue;

      Temp := FStack.Push(ntField);
      if (IsClassVarSection) then Temp.Attribute[anClass]:= AttributeValues[atTrue];
      try
        Temp.AssignPositionFrom(Field);

        FStack.AddChild(Field.Clone);
        TypeInfo := TypeInfo.Clone;
        if Assigned(TypeArgs) then
          TypeInfo.AddChild(TypeArgs.Clone);
        FStack.AddChild(TypeInfo);
      finally
        FStack.Pop;
      end;
    end;
  finally
    Fields.Free;
  end;
end;

procedure TPasSyntaxTreeBuilder.ObjectField;
var
  Fields, Temp: TSyntaxNode;
  Field, TypeInfo, TypeArgs: TSyntaxNode;
  IsClassVarSection: boolean;
begin
  IsClassVarSection:= FStack.Peek.HasAttribute(anClass);
  Fields := TSyntaxNode.Create(ntFields);
  try
    FStack.Push(Fields);
    try
      inherited;
    finally
      FStack.Pop;
    end;

    TypeInfo := Fields.FindNode(ntType);
    TypeArgs := Fields.FindNode(ntTypeArgs);
    for Field in Fields.ChildNodes do
    begin
      if Field.Typ <> ntName then
        Continue;

      Temp := FStack.Push(ntField);
      if (IsClassVarSection) then Temp.Attribute[anClass]:= AttributeValues[atTrue];
      try
        Temp.AssignPositionFrom(Field);

        FStack.AddChild(Field.Clone);
        TypeInfo := TypeInfo.Clone;
        if Assigned(TypeArgs) then
          TypeInfo.AddChild(TypeArgs.Clone);
        FStack.AddChild(TypeInfo);
      finally
        FStack.Pop;
      end;
    end;
  finally
    Fields.Free;
  end;
end;

procedure TPasSyntaxTreeBuilder.FieldList;
var
  Fields, Temp: TSyntaxNode;
  Field, TypeInfo, TypeArgs: TSyntaxNode;
  IsClassVarSection: boolean;
begin
  IsClassVarSection:= FStack.Peek.HasAttribute(anClass);
  Fields := TSyntaxNode.Create(ntFields);
  try
    FStack.Push(Fields);
    try
      inherited;
    finally
      FStack.Pop;
    end;

    TypeInfo := Fields.FindNode(ntType);
    TypeArgs := Fields.FindNode(ntTypeArgs);
    for Field in Fields.ChildNodes do
    begin
      if Field.Typ <> ntName then
        Continue;

      Temp := FStack.Push(ntField);
      if (IsClassVarSection) then Temp.Attribute[anClass]:= AttributeValues[atTrue];
      try
        Temp.AssignPositionFrom(Field);

        FStack.AddChild(Field.Clone);
        TypeInfo := TypeInfo.Clone;
        if Assigned(TypeArgs) then
          TypeInfo.AddChild(TypeArgs.Clone);
        FStack.AddChild(TypeInfo);
      finally
        FStack.Pop;
      end;
    end;
  finally
    Fields.Free;
  end;
end;

Note the issue of a nasty case of copy-paste anti-pattern, but that's another ticket.