chapel icon indicating copy to clipboard operation
chapel copied to clipboard

LSP: fix "call hierarchy" across files

Open DanilaFe opened this issue 4 months ago • 0 comments

In the following program, trying to get the call hierarchy for writeln did not work on main.

writeln("Hello, world!");

There were a few issues with this. The first issue is that the the "index" that was fed through a CallHierarchyItem to LSP and back to CLS was an index into a single file's list of instantiations. Thus, if the function was instantiated in one place, but defined in another, the index would not be valid (or worse, be incorrect). This PR changes this by changing the way typed signatures are mapped to JSON-compatible identifiers; they are instead registered with a ContextContainer object, getting a unique ID. The unique ID is then used as JSON data, and can be used to access the same TypedSignature object when the JSON is being deserialized.

This, however, was not enough. The next problem was that we currently create a new ContextContainer per file (to handle the case in which multiple files with the same name / module name exist). As a result of this, writeln that is called in module A and defined in module B will have its instantiation computed using A's context, but its AST and other information will use B's context. This is troublesome. This PR adjusts the situation by changing the file -> FileInfo mapping to be a (file, context id) -> FileInfo mapping. This way, the same file can have several contexts (e.g., if a standard library file is loaded from two distinct files, but both named A.chpl). By default (e.g., when opening a file), the (file, "None") key is used (since no particular context was requested). However, if a file A needs to show an instantiation (via file info) from file B, we create a new mapping (fileB, fileA.context.id) -> fileInfoB, which is created from the same context. This ensures that there is a file information object for file B with the same context as that of file A.

When a call hierarchy item is constructed, it now specifies what context was used to create it. Thus, if other CallHierarchyItems point to other files, these other files are opened with the same context. To communicate the context over JSON, I employ the same approach as I did with typed signatures (register a context object with unique ID, use the ID to marshal the context to and from JSON).

To fix the case of writeln in particular, I had to relax an assertion from the _owned/_shared_ resolution PR https://github.com/chapel-lang/chapel/pull/25617. This led to some simplified code in any case, which is great. I believe @arezaii is fine with this change.

Testing

  • [x] LSP tests
  • [x] dyno tests

DanilaFe avatar Oct 04 '24 00:10 DanilaFe