eclipse-jdtls / eclipse.jdt.ls

Java language server
1.8k stars 400 forks source link

Outgoing call hierarchies sometimes duplicate the results #3193

Open bstaletic opened 4 months ago

bstaletic commented 4 months ago
class C {
  public static void f() {}
  public C() {
      f();
      f();
  }
}

Requesting outgoing calls on the constructor returns 2 items, each containing 2 call sites.

Prepare call hierarchies request:

{
  "id": 2,
  "jsonrpc": "2.0",
  "method": "textDocument/prepareCallHierarchy",
  "params": {
    "position": {
      "character": 9,
      "line": 2
    },
    "textDocument": {
      "uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java"
    }
  }
}

Prepare call hierarchies response:

{
  "id": 2,
  "jsonrpc": "2.0",
  "method": "textDocument/prepareCallHierarchy",
  "params": {
    "position": {
      "character": 9,
      "line": 2
    },
    "textDocument": {
      "uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java"
    }
  }
}

Outgoing calls request:

{
  "id": 3,
  "jsonrpc": "2.0",
  "method": "callHierarchy/outgoingCalls",
  "params": {
    "item": {
      "detail": "C",
      "kind": 9,
      "name": "C()",
      "range": {
        "end": {
          "character": 3,
          "line": 5
        },
        "start": {
          "character": 2,
          "line": 2
        }
      },
      "selectionRange": {
        "end": {
          "character": 10,
          "line": 2
        },
        "start": {
          "character": 9,
          "line": 2
        }
      },
      "uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java"
    }
  }
}

Outgoing calls response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": [
    {
      "to": {
        "name": "f() : void",
        "detail": "C",
        "kind": 6,
        "uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java",
        "range": {
          "start": {
            "line": 1,
            "character": 2
          },
          "end": {
            "line": 1,
            "character": 27
          }
        },
        "selectionRange": {
          "start": {
            "line": 1,
            "character": 21
          },
          "end": {
            "line": 1,
            "character": 22
          }
        }
      },
      "fromRanges": [
        {
          "start": {
            "line": 3,
            "character": 3
          },
          "end": {
            "line": 3,
            "character": 6
          }
        },
        {
          "start": {
            "line": 4,
            "character": 3
          },
          "end": {
            "line": 4,
            "character": 6
          }
        }
      ]
    },
    {
      "to": {
        "name": "f() : void",
        "detail": "C",
        "kind": 6,
        "uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java",
        "range": {
          "start": {
            "line": 1,
            "character": 2
          },
          "end": {
            "line": 1,
            "character": 27
          }
        },
        "selectionRange": {
          "start": {
            "line": 1,
            "character": 21
          },
          "end": {
            "line": 1,
            "character": 22
          }
        }
      },
      "fromRanges": [
        {
          "start": {
            "line": 3,
            "character": 3
          },
          "end": {
            "line": 3,
            "character": 6
          }
        },
        {
          "start": {
            "line": 4,
            "character": 3
          },
          "end": {
            "line": 4,
            "character": 6
          }
        }
      ]
    }
  ]
}

Entire message exchange, from the client's side:

2024-06-13 12:02:32,845 - DEBUG - TX: Sending message: b'Content-Length: 1942\r\n\r\n{"id":1,"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}}},"completion":{"completionItem":{"documentationFormat":["plaintext","markdown"],"resolveSupport":{"properties":["documentation","detail"]}},"completionItemKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]}},"documentSymbol":{"hierarchicalDocumentSymbolSupport":false,"labelSupport":false,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}},"hover":{"contentFormat":["plaintext","markdown"]},"inlay_hint":{},"semanticTokens":{"augmentSyntaxTokens":true,"formats":["relative"],"requests":{"full":{"delta":false},"range":true},"tokenModifiers":[],"tokenTypes":["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","event","function","method","member","macro","keyword","modifier","comment","string","number","regexp","operator"]},"signatureHelp":{"signatureInformation":{"documentationFormat":["plaintext","markdown"],"parameterInformation":{"labelOffsetSupport":true}}},"synchronization":{"didSave":true}},"workspace":{"applyEdit":true,"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}},"workspaceEdit":{"documentChanges":true},"workspaceFolders":true}},"initializationOptions":{"bundles":[]},"processId":11792,"rootPath":"/home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t","rootUri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t","workspaceFolders":[{"name":"t","uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t"}]}}'
2024-06-13 12:02:36,936 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"language/status","params":{"type":"Starting","message":"Init..."}}'
2024-06-13 12:02:36,940 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"language/status","params":{"type":"Starting","message":"0% Starting Java Language Server"}}'
2024-06-13 12:02:36,956 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","id":1,"result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":2,"save":{"includeText":true}},"hoverProvider":true,"completionProvider":{"resolveProvider":true,"triggerCharacters":[".","@","#","*"," "]},"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"workspaceSymbolProvider":true,"codeActionProvider":{"codeActionKinds":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"],"resolveProvider":false},"codeLensProvider":{"resolveProvider":true},"documentFormattingProvider":true,"documentRangeFormattingProvider":true,"documentOnTypeFormattingProvider":{"firstTriggerCharacter":";","moreTriggerCharacter":["\\n","}"]},"renameProvider":{"prepareProvider":true},"foldingRangeProvider":true,"declarationProvider":true,"executeCommandProvider":{"commands":["java.project.import","java.project.changeImportedProjects","java.navigate.openTypeHierarchy","java.project.resolveStackTraceLocation","java.edit.handlePasteEvent","java.edit.stringFormatting","java.project.getSettings","java.project.resolveWorkspaceSymbol","java.project.upgradeGradle","java.project.createModuleInfo","java.vm.getAllInstalls","java.edit.organizeImports","java.project.refreshDiagnostics","java.project.removeFromSourcePath","java.project.listSourcePaths","java.project.updateSettings","java.project.getAll","java.reloadBundles","java.project.isTestFile","java.project.resolveText","java.project.getClasspaths","java.navigate.resolveTypeHierarchy","java.edit.smartSemicolonDetection","java.project.updateSourceAttachment","java.project.updateClassPaths","java.decompile","java.protobuf.generateSources","java.project.resolveSourceAttachment","java.project.updateJdk","java.project.addToSourcePath","java.completion.onDidSelect"]},"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":true}},"typeHierarchyProvider":true,"callHierarchyProvider":true,"selectionRangeProvider":true,"semanticTokensProvider":{"legend":{"tokenTypes":["namespace","class","interface","enum","enumMember","type","typeParameter","method","property","variable","parameter","modifier","keyword","annotation","annotationMember","record","recordComponent"],"tokenModifiers":["abstract","static","readonly","deprecated","declaration","documentation","public","private","protected","native","generic","typeArgument","importDeclaration","constructor"]},"range":false,"full":{"delta":false},"documentSelector":[{"language":"java","scheme":"file"},{"language":"java","scheme":"jdt"}]},"inlayHintProvider":true}}}'
2024-06-13 12:02:36,958 - DEBUG - TX: Sending notification: b'Content-Length: 52\r\n\r\n{"jsonrpc":"2.0","method":"initialized","params":{}}'
2024-06-13 12:02:36,958 - DEBUG - TX: Sending notification: b'Content-Length: 98\r\n\r\n{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"bundles":[]}}}'
2024-06-13 12:02:36,959 - DEBUG - TX: Sending notification: b'Content-Length: 320\r\n\r\n{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"java","text":"class C {\\n  public static void f() {}\\n  public C() {\\n\\t  f();\\n\\t  f();\\n  }\\n}\\n","uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java","version":1}}}'
2024-06-13 12:02:36,986 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"language/status","params":{"type":"ProjectStatus","message":"OK"}}'
2024-06-13 12:02:36,986 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"language/status","params":{"type":"Starting","message":"100% Starting Java Language Server"}}'
2024-06-13 12:02:36,987 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"language/status","params":{"type":"Started","message":"Ready"}}'
2024-06-13 12:02:36,989 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"language/status","params":{"type":"Starting","message":"100% Starting Java Language Server"}}'
2024-06-13 12:02:36,998 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","id":"1","method":"client/registerCapability","params":{"registrations":[{"id":"4eaf146a-12ae-4e82-befe-98414fc068fd","method":"workspace/didChangeWorkspaceFolders"}]}}'
2024-06-13 12:02:36,998 - DEBUG - TX: Sending response: b'Content-Length: 40\r\n\r\n{"id":"1","jsonrpc":"2.0","result":null}'
2024-06-13 12:02:36,998 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"language/status","params":{"type":"ServiceReady","message":"ServiceReady"}}'
2024-06-13 12:02:37,020 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","id":"2","method":"client/registerCapability","params":{"registrations":[{"id":"617416cd-01ea-4685-821b-3756256ef360","method":"workspace/didChangeWatchedFiles","registerOptions":{"watchers":[{"globPattern":"**/*.java"},{"globPattern":"**/.project"},{"globPattern":"**/.classpath"},{"globPattern":"**/.settings/*.prefs"},{"globPattern":"**/src/**"},{"globPattern":"**/*.gradle"},{"globPattern":"**/*.gradle.kts"},{"globPattern":"**/gradle.properties"},{"globPattern":"**/pom.xml"}]}}]}}'
2024-06-13 12:02:37,022 - DEBUG - TX: Sending response: b'Content-Length: 40\r\n\r\n{"id":"2","jsonrpc":"2.0","result":null}'
2024-06-13 12:02:38,508 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/workspace/temp/tmproquhvpm/t_dfbc5e74","diagnostics":[]}}'
2024-06-13 12:02:38,680 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java","diagnostics":[]}}'
2024-06-13 12:02:38,808 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/workspace/temp/tmproquhvpm/t_dfbc5e74","diagnostics":[]}}'
2024-06-13 12:02:39,538 - DEBUG - TX: Sending message: b'Content-Length: 250\r\n\r\n{"id":2,"jsonrpc":"2.0","method":"textDocument/prepareCallHierarchy","params":{"position":{"character":9,"line":2},"textDocument":{"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java"}}}'
2024-06-13 12:02:40,011 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","id":2,"result":[{"name":"C()","detail":"C","kind":9,"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java","range":{"start":{"line":2,"character":2},"end":{"line":5,"character":3}},"selectionRange":{"start":{"line":2,"character":9},"end":{"line":2,"character":10}}}]}'
2024-06-13 12:02:41,168 - DEBUG - TX: Sending message: b'Content-Length: 393\r\n\r\n{"id":3,"jsonrpc":"2.0","method":"callHierarchy/outgoingCalls","params":{"item":{"detail":"C","kind":9,"name":"C()","range":{"end":{"character":3,"line":5},"start":{"character":2,"line":2}},"selectionRange":{"end":{"character":10,"line":2},"start":{"character":9,"line":2}},"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java"}}}'
2024-06-13 12:02:41,246 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","id":3,"result":[{"to":{"name":"f() : void","detail":"C","kind":6,"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java","range":{"start":{"line":1,"character":2},"end":{"line":1,"character":27}},"selectionRange":{"start":{"line":1,"character":21},"end":{"line":1,"character":22}}},"fromRanges":[{"start":{"line":3,"character":3},"end":{"line":3,"character":6}},{"start":{"line":4,"character":3},"end":{"line":4,"character":6}}]},{"to":{"name":"f() : void","detail":"C","kind":6,"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t/MethodsWithDocumentation.java","range":{"start":{"line":1,"character":2},"end":{"line":1,"character":27}},"selectionRange":{"start":{"line":1,"character":21},"end":{"line":1,"character":22}}},"fromRanges":[{"start":{"line":3,"character":3},"end":{"line":3,"character":6}},{"start":{"line":4,"character":3},"end":{"line":4,"character":6}}]}]}'

JDT log

!SESSION 2024-06-13 12:02:33.017 -----------------------------------------------
eclipse.buildId=unknown
java.version=17.0.11
java.vendor=Eclipse Adoptium
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=en_US
Command-line arguments:  -data /home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/workspace/temp/tmproquhvpm

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:35.184
!MESSAGE class org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin is started

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:35.482
!MESSAGE Main thread is waiting

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:35.524
!MESSAGE >> initialize

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:35.528
!MESSAGE Initializing Java Language Server 1.36.0.202405301306

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:35.529
!MESSAGE Started org.eclipse.m2e.core 1ms

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:36.842
!MESSAGE ProjectRegistryRefreshJob finished 1312ms

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:36.870
!MESSAGE Started org.eclipse.buildship.core 27ms

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:36.923
!MESSAGE Static Commands: []

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:36.924
!MESSAGE Non-Static Commands: [java.project.import, java.project.changeImportedProjects, java.navigate.openTypeHierarchy, java.project.resolveStackTraceLocation, java.edit.handlePasteEvent, java.edit.stringFormatting, java.project.getSettings, java.project.resolveWorkspaceSymbol, java.project.upgradeGradle, java.project.createModuleInfo, java.vm.getAllInstalls, java.edit.organizeImports, java.project.refreshDiagnostics, java.project.removeFromSourcePath, java.project.listSourcePaths, java.project.updateSettings, java.project.getAll, java.reloadBundles, java.project.isTestFile, java.project.resolveText, java.project.getClasspaths, java.navigate.resolveTypeHierarchy, java.edit.smartSemicolonDetection, java.project.updateSourceAttachment, java.project.updateClassPaths, java.decompile, java.protobuf.generateSources, java.project.resolveSourceAttachment, java.project.updateJdk, java.project.addToSourcePath, java.completion.onDidSelect]

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:36.941
!MESSAGE RepositoryRegistryUpdateJob finished 0ms

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:36.960
!MESSAGE >> initialized

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:36.986
!MESSAGE Workspace initialized in 45ms

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:36.992
!MESSAGE >> initialization job finished

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:37.013
!MESSAGE >> build jobs finished

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:37.014
!MESSAGE >> registerWatchers'

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:37.017
!MESSAGE >> registerFeature 'workspace/didChangeWatchedFiles'

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:37.103
!MESSAGE Try to create an invisible project for the workspace /home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/t

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:37.104
!MESSAGE Creating the Java project t_dfbc5e74

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:37.420
!MESSAGE Finished creating the Java project t_dfbc5e74

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:37.428
!MESSAGE Successfully created a workspace invisible project t_dfbc5e74

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:37.948
!MESSAGE Reconciled 1. Took 0 ms

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:38.514
!MESSAGE >> Updating classpath for project t_dfbc5e74

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:38.669
!MESSAGE begin problem for /MethodsWithDocumentation.java

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:38.674
!MESSAGE 0 problems reported for /MethodsWithDocumentation.java

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-06-13 12:02:38.679
!MESSAGE Validated 1. Took 79 ms

JDT stderr:

Jun 13, 2024 12:02:33 PM org.apache.aries.spifly.BaseActivator log
INFO: Registered provider ch.qos.logback.classic.servlet.LogbackServletContainerInitializer of service jakarta.servlet.ServletContainerInitializer in bundle ch.qos.logback.classic
Jun 13, 2024 12:02:33 PM org.apache.aries.spifly.BaseActivator log
INFO: Registered provider ch.qos.logback.classic.spi.LogbackServiceProvider of service org.slf4j.spi.SLF4JServiceProvider in bundle ch.qos.logback.classic
rgrunber commented 3 months ago

I think this is closely related to what I observed in https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/1824#issuecomment-914607015 .

bstaletic commented 3 months ago

@rgrunber That seems like the same problem indeed. I am using fromRanges to construct some internal location type.

TomKrcmar commented 1 month ago

I am experiencing this as well.

I am able to de-dupe them by keying on the range of the CallHierarchyItem and resolving them in a map, but if I try to do the same de-duping for other LSP servers, the results aren't the same. If I key on selectionRange for those other servers, they all work - only JDTLS works with range to de-dupe.

https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/3184 probably explains why I can't de-dupe consistently.