========================================================================
Simple procedure
========================================================================

codeunit 50100 "My Codeunit"
{
    procedure Foo()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (quoted_identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block))))

========================================================================
Procedure with parameters
========================================================================

codeunit 50100 Test
{
    procedure DoSomething(Param1: Integer; Param2: Text)
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (parameter_list
        (parameter
          (identifier)
          (type_specification
            (basic_type)))
        (parameter
          (identifier)
          (type_specification
            (text_type))))
      (code_block))))

========================================================================
Procedure with var parameters
========================================================================

codeunit 50100 Test
{
    procedure DoSomething(var Customer: Record "Customer")
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (parameter_list
        (parameter
          (var_keyword)
          (identifier)
          (type_specification
            (record_type
              (quoted_identifier)))))
      (code_block))))

========================================================================
Procedure with return type
========================================================================

codeunit 50100 Test
{
    procedure GetValue(): Boolean
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (type_specification
        (basic_type))
      (code_block))))

========================================================================
Procedure with named return value
========================================================================

codeunit 50100 Test
{
    procedure GetValue() result: Boolean
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (identifier)
      (type_specification
        (basic_type))
      (code_block))))

========================================================================
Local procedure modifier
========================================================================

codeunit 50100 Test
{
    local procedure Helper()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_modifier
        (local_keyword))
      (procedure_keyword)
      (identifier)
      (code_block))))

========================================================================
Internal procedure modifier
========================================================================

codeunit 50100 Test
{
    internal procedure InternalProc()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_modifier
        (internal_keyword))
      (procedure_keyword)
      (identifier)
      (code_block))))

========================================================================
Protected procedure modifier
========================================================================

codeunit 50100 Test
{
    protected procedure ProtectedProc()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_modifier
        (protected_keyword))
      (procedure_keyword)
      (identifier)
      (code_block))))

========================================================================
Procedure with var section
========================================================================

codeunit 50100 Test
{
    procedure Calculate()
    var
        x: Integer;
        y: Decimal;
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_keyword)
      (identifier)
      (var_section
        (var_keyword)
        (variable_declaration
          (identifier)
          (type_specification
            (basic_type)))
        (variable_declaration
          (identifier)
          (type_specification
            (basic_type))))
      (code_block))))

========================================================================
Procedure with parameters, return type, and var section
========================================================================

codeunit 50100 Test
{
    local procedure Process(Input: Text[100]; var Result: Record "Sales Header"): Boolean
    var
        TempRec: Record "Sales Line";
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (procedure
      (procedure_modifier
        (local_keyword))
      (procedure_keyword)
      (identifier)
      (parameter_list
        (parameter
          (identifier)
          (type_specification
            (text_type
              (integer))))
        (parameter
          (var_keyword)
          (identifier)
          (type_specification
            (record_type
              (quoted_identifier)))))
      (type_specification
        (basic_type))
      (var_section
        (var_keyword)
        (variable_declaration
          (identifier)
          (type_specification
            (record_type
              (quoted_identifier)))))
      (code_block))))

========================================================================
Trigger declaration
========================================================================

codeunit 50100 Test
{
    trigger OnRun()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (trigger_declaration
      (trigger_keyword)
      (identifier)
      (code_block))))

========================================================================
Trigger with var section
========================================================================

table 50100 MyTable
{
    trigger OnInsert()
    var
        x: Integer;
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (table_declaration
    (table_keyword)
    (integer)
    (identifier)
    (trigger_declaration
      (trigger_keyword)
      (identifier)
      (var_section
        (var_keyword)
        (variable_declaration
          (identifier)
          (type_specification
            (basic_type))))
      (code_block))))

========================================================================
Variable declarations in object body
========================================================================

codeunit 50100 Test
{
    var
        Customer: Record "Customer";
        Amount: Decimal;
        MyList: List of [Text];
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (var_section
      (var_keyword)
      (variable_declaration
        (identifier)
        (type_specification
          (record_type
            (quoted_identifier))))
      (variable_declaration
        (identifier)
        (type_specification
          (basic_type)))
      (variable_declaration
        (identifier)
        (type_specification
          (list_type
            (type_specification
              (text_type))))))))

========================================================================
Attribute before procedure
========================================================================

codeunit 50100 Test
{
    [Scope('OnPrem')]
    procedure MyProc()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (attribute_item
      (attribute_content
        (identifier)
        (attribute_arguments
          (attribute_argument_list
            (string_literal)))))
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block))))

========================================================================
Multiple attributes before procedure
========================================================================

codeunit 50100 Test
{
    [IntegrationEvent(false, false)]
    [Scope('OnPrem')]
    procedure MyEvent()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (attribute_item
      (attribute_content
        (identifier)
        (attribute_arguments
          (attribute_argument_list
            (boolean)
            (boolean)))))
    (attribute_item
      (attribute_content
        (identifier)
        (attribute_arguments
          (attribute_argument_list
            (string_literal)))))
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block))))

========================================================================
Attribute without arguments
========================================================================

codeunit 50100 Test
{
    [NonDebuggable]
    procedure Secret()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (attribute_item
      (attribute_content
        (identifier)))
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block))))

========================================================================
Multiple procedures in codeunit
========================================================================

codeunit 50100 Test
{
    trigger OnRun()
    begin
    end;

    local procedure Helper()
    begin
    end;

    procedure DoWork()
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (trigger_declaration
      (trigger_keyword)
      (identifier)
      (code_block))
    (procedure
      (procedure_modifier
        (local_keyword))
      (procedure_keyword)
      (identifier)
      (code_block))
    (procedure
      (procedure_keyword)
      (identifier)
      (code_block))))

========================================================================
Quoted variable name
========================================================================

codeunit 50100 Test
{
    var
        "My Quoted Var": Integer;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (var_section
      (var_keyword)
      (variable_declaration
        (quoted_identifier)
        (type_specification
          (basic_type))))))

========================================================================
Trigger with parameters
========================================================================

codeunit 50100 Test
{
    trigger OnAfterValidate(var Rec: Record "Sales Header"; var xRec: Record "Sales Header")
    begin
    end;
}

------------------------------------------------------------------------

(source_file
  (codeunit_declaration
    (codeunit_keyword)
    (integer)
    (identifier)
    (trigger_declaration
      (trigger_keyword)
      (identifier)
      (parameter_list
        (parameter
          (var_keyword)
          (identifier)
          (type_specification
            (record_type
              (quoted_identifier))))
        (parameter
          (var_keyword)
          (identifier)
          (type_specification
            (record_type
              (quoted_identifier)))))
      (code_block))))
