tree-sitter-c icon indicating copy to clipboard operation
tree-sitter-c copied to clipboard

fix: Add compound statement to call expression

Open tjdevries opened this issue 3 years ago • 0 comments

If you have code like the following:

#define TAKES_BLOCK(x, block) for (i = 0; i < x; i++) block

int main(void) {
  {
    int x = 0;
  }
  TAKES_BLOCK(10, {
    // Doesn't matter what I put in here
  });
}

You get the following problem:

translation_unit [0, 0] - [10, 0])
  preproc_function_def [0, 0] - [2, 0])
    name: identifier [0, 8] - [0, 19])
    parameters: preproc_params [0, 19] - [0, 29])
      identifier [0, 20] - [0, 21])
      identifier [0, 23] - [0, 28])
    value: preproc_arg [0, 29] - [0, 59])
  function_definition [2, 0] - [9, 1])
    type: primitive_type [2, 0] - [2, 3])
    declarator: function_declarator [2, 4] - [2, 14])
      declarator: identifier [2, 4] - [2, 8])
      parameters: parameter_list [2, 8] - [2, 14])
        parameter_declaration [2, 9] - [2, 13])
          type: primitive_type [2, 9] - [2, 13])
    body: compound_statement [2, 15] - [9, 1])
      compound_statement [3, 2] - [5, 3])
        declaration [4, 4] - [4, 14])
          type: primitive_type [4, 4] - [4, 7])
          declarator: init_declarator [4, 8] - [4, 13])
            declarator: identifier [4, 8] - [4, 9])
            value: number_literal [4, 12] - [4, 13])
      expression_statement [6, 2] - [8, 5])
        call_expression [6, 2] - [8, 4])
          function: identifier [6, 2] - [6, 13])
          arguments: argument_list [6, 13] - [8, 4])
            number_literal [6, 14] - [6, 16])
            ERROR [6, 16] - [8, 3])
              comment [7, 4] - [7, 40])

(This error node is much more destructive in large functions and/or nested if statements, I think because the {} gets out-of-sync)

You expect to be able to pass in compound_statements.

As far as I can tell, there is no way to tell the difference between macro expansions and regular function calls, so I don't think I can limit this to macros only.

The reason I add this is I have a much more complicated example where the for loop is managed via the macro and the rest is expanded via a block. If I do this, the entire rest of the function loses its state in a series of if statements and things get very confused.

If this isn't a good fix / you want something else, let me know or just close. Thanks.

tjdevries avatar Jun 01 '21 16:06 tjdevries