weixin_39569112
weixin_39569112
2020-12-02 15:06

Annotate references with the name of the function in which they occur

When performing Find References, it would be really useful if each reference was annotated with the name of the functin in which the reference occurs (in addition to the name of the file, which is already there).

该提问来源于开源项目:jacobdufault/cquery

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

13条回答

  • weixin_39569112 weixin_39569112 5月前

    As a point of comparison, consider the search results pane in Eclipse CDT:

    cfviz-refs-eclipse

    There is no preview window, just a copy of the line containing the reference, but the search result is annotated with the name of the function it's contained in.

    点赞 评论 复制链接分享
  • weixin_39749501 weixin_39749501 5月前

    interface ReferenceParams extends TextDocumentPositionParams { returns Location[] | null. I think TypeScript interfaces can be arbitrarily inherited so we can add extra fields to Location. But this requires UI support from language clients.

    What is needed to be done on cquery's side:

    • Extend struct VarDefDefinitionData to add semantic container (a named container)
    • Support serialization of subclasses. This requires some pointer or std::unique_ptr to utilize virtual functions, or use ad-hoc type dispatching.
    点赞 评论 复制链接分享
  • weixin_40001025 weixin_40001025 5月前

    Why can't we just add the information to TextDocumentPositionParams (or some derived type that the references message uses)? This approach eliminates the need for subclass serialization.

    点赞 评论 复制链接分享
  • weixin_39569112 weixin_39569112 5月前

    Why can't we just add the information to TextDocumentPositionParams (or some derived type that the references message uses)? This approach eliminates the need for subclass serialization.

    TextDocumentPositionParams is what the request message uses. We need a place to put the information in the response message, whose type is just Location[] | null.

    点赞 评论 复制链接分享
  • weixin_39749501 weixin_39749501 5月前

    this requires more info in QueryLocation and uses. I recently changed Id from size_t to uint32_t

    c++
    // 12 bytes
    struct QueryLocation {
      QueryFileId path; // 4 bytes
      Range range; // 8 bytes
    };
    
    struct QueryVar {
    ...
        std::vector<querylocation> uses;
    };
    </querylocation>

    We should think how to encode the parent symbol information without bloating the size too much.

    c++
    struct IndexVar {
      ...
      std::vector<range> uses;
    };
    </range>
    点赞 评论 复制链接分享
  • weixin_39569112 weixin_39569112 5月前

    It looks like the necessary information is available from libclang via CXIdxEntityRefInfo::container. Currently, we only use it for functions, to populate IndexFuncRef::id inside IndexFunc::callers. To implement this fully, we will need to store the container for variable and type references as well.

    点赞 评论 复制链接分享
  • weixin_39749501 weixin_39749501 5月前

    For a symbol occurrence (uses variables in query.h and indexer.h), what we need to record:

    • Range range;
    • Maybe<Id<void>> parent; container information
    • QueryFileId path;
    • SymbolKind parent_kind for a variable, the container may be either a type or a function. there should be someway to differentiate them.
    • CXSymbolRole read/write/call ...

    QueryFileId path; looks to me the most useless one, but we may need to encode the file information in Query{Func,Type,Var} so that we can get the file associate with a uses entry by looking up its Query{Func,Type,Var} entry.

    点赞 评论 复制链接分享
  • weixin_39569112 weixin_39569112 5月前

    I filed an LSP spec issue for this: https://github.com/Microsoft/language-server-protocol/issues/396.

    点赞 评论 复制链接分享
  • weixin_39749501 weixin_39749501 5月前

    Renamed {Index,Query}File::callers to uses because the uses can also be f = &foo;

    360a4ca0ebf057ff4b32c66bb8ccd2f121d79738 added config->extension.referenceContainer but someone should turn all

    c++
      Maybe<typename f::range> definition_spelling;
      Maybe<typename f::range> definition_extent;
    </typename></typename>

    to Use (because Use records the lexical parent information)

    点赞 评论 复制链接分享
  • weixin_39749501 weixin_39749501 5月前

    The uses of Query{Func,Type,Var} have been unified to std::vector<Use> uses;

    c++
    struct IndexFunc {
    ...
      std::vector<use> uses;
    };
    </use>

    Use::kind Use::id represents the lexical parent.

    点赞 评论 复制链接分享
  • weixin_39569112 weixin_39569112 5月前

    Sure. Given this code:

    
    void target();
    
    void function1() {
      target();
    }
    
    void function2() {
      target();
    }
    

    when you perform "Find References" on target, and, say, the reference in function1() is selected:

    cfviz-refs

    I would like to see function1 either at the top beside "test.cpp - 3 references", or in the side panel next to the entry being viewed (in which case, it can be there even when the entry is not selected).

    (In this case, you can see function1 in the code preview, but imagine it was a longer function so you couldn't see its name without scrolling up, potentially a lot.)

    点赞 评论 复制链接分享
  • weixin_39569112 weixin_39569112 5月前

    I don't think it's a VSCode issue, because the server only sends the reference's character range:

    
        {
          "uri": "file:///home/nr/dev/projects/testing/test/test.cpp",
          "range": {
            "start": {
              "line": 3,
              "character": 2
            },
            "end": {
              "line": 3,
              "character": 8
            }
          }
        },
    

    To implement this feature, the server would also need to send the name of the enclosing function for each reference.

    点赞 评论 复制链接分享
  • weixin_40001025 weixin_40001025 5月前

    Can you share a screenshot? This is likely a vscode issue that cannot be fixed by cquery.

    点赞 评论 复制链接分享

相关推荐