citre icon indicating copy to clipboard operation
citre copied to clipboard

Accurate inspection on C struct members

Open AmaiKinono opened this issue 3 years ago • 6 comments

Several Citre users talked about this idea to me.

If we are at:

foo.bar|

(| is the cursor), we could:

  1. Find the definitons of foo (we could assume it's a variable, function parameter, or member (maybe more?)).
  2. Find the typeref fields of these definitions. They should be typeref:struct:structName (if there are more than 1 definitons, multiple structName is possible.
  3. Sort the definitions of bar so those with struct:structName scope field are on the top.

I need to learn more on how a C file is tagged:

  • For foo->bar, foo is a pointer. What does its typeref field look like?

Also, some users want struct member completion in this situation:

foo.|

We could do 1 and 2 the same as above, then:

  • Filter all tags and find those with appropriate scope info. This can be slow.
  • Or, assume qualified tags are enabled, then we could look for tags start with structName.. This should be fast.

I'd like to take the latter approach. The infrastructure of Citre needs some mild modify to support it, though.

If we could solve this, the design can be used for other static type languages, too. If we could also find the way of dealing with inheritance, I'd say Citre will have the potential of becoming the best tool for static type languages with class/subtype or even other fancy type systems.

AmaiKinono avatar Aug 10 '21 08:08 AmaiKinono

If everything can be done in ctags/readtags, it is nice. If we don't seek the above ideal, there are more choices. which-function-mode tells us the current scope. You can call readtags to find foo with (eq? $scope-name (the-scope-information-getting-from-which-mode)).

masatake avatar Aug 10 '21 10:08 masatake

Using https://github.com/universal-ctags/python-ctags3 is just another choice.

masatake avatar Aug 10 '21 10:08 masatake

  1. which-function-mode actually uses imenu, AFAIK. imenu doesn't know where does a scope end, so it can't tell you the current scope accurately.

  2. I didn't see connection between the question I described and the current scope.

    What I want is:

    • find the symbol before .
    • find the tags of the symbol (it should be a struct instance)
    • find the type of those tags (some kind of a struct)
    • now we know the symbol after . should be a member of that struct. We can sort those results above others.

AmaiKinono avatar Aug 10 '21 11:08 AmaiKinono

  • find the tags of the symbol (it should be a struct instance) (B)

(B) can be done in readtags. However, readtags may provide multiple candidates.

struct port {
   uint16_t num;
   enum protocol proto;
};

extern struct port p;
void print_point(struct point p)
{
    printf("%d %d\n", p.|
}

How can we know the type of p? readtags may report:

p	foo.c	/^extern struct port p;$/;"	x	typeref:struct:port
p	foo.c	/^void print_point(struct point p)$/;"	z	function:print_point	typeref:struct:point	file:

If we know the cursor is in print_point, citre can choose the latter one.

a tag entry of C language can have line: and end: fields. So we can implement (B) only with readtags. However, it will need a linear search that we don't want to do.

BTW we cannot forget typedef.

struct point;
typedef struct point Point;
Point p;

In that case, citre must run readtags repeatedly.

masatake avatar Aug 10 '21 18:08 masatake

readtags may provide multiple candidates... If we know the cursor is in print_point, citre can choose the latter one.

I see.

a tag entry of C language can have line: and end: fields. So we can implement (B) only with readtags. However, it will need a linear search that we don't want to do.

Also, this won't work if the file has been edited, so the line length of the function is no longer (- end-field line-field).

What we could do is do some parsing in Citre to find the current function.

Using which-function-mode is not a choice because it uses imenu, and when citre-mode is on, imenu does a linear search on the tags file.

Also, when we couldn't do better, we can just use all definitons of p. The point is not to do a complete semantic analysis, but trying to be accurate when guessing things.

BTW we cannot forget typedef. In that case, citre must run readtags repeatedly.

Thanks, I didn't thought about typedef. I'm prepared to running readtags multiple times, though.

AmaiKinono avatar Aug 11 '21 02:08 AmaiKinono

Using which-function-mode is not a choice because it uses imenu, and when citre-mode is on, imenu does a linear search on the tags file.

In such a case, you can turn off citre-mode temporarily.

masatake avatar Aug 11 '21 09:08 masatake

As discussed in the developer manual, we've decided to not take the approach to filter accurately as this may throw away actually useful tags. So I'll close this.

AmaiKinono avatar Apr 21 '24 08:04 AmaiKinono