Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

textDocument/completion payload sizes can be very large because of documentation of in-scope items #55790

Open
onism0106 opened this issue May 21, 2024 · 7 comments
Labels
analyzer-completion Issues with the analysis server's code completion feature area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P3 A lower priority bug or feature request type-enhancement A request for a change that isn't a bug

Comments

@onism0106
Copy link

When using the textDocument/completion method for code completion, a large amount of irrelevant information is returned, including the documentation field. How can I solve this issue? The editor is a custom code editor implemented with Flutter. I have set "suggestFromUnimportedLibraries": false during initialization, but it has not had any effect.

@mkustermann mkustermann added the area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. label May 21, 2024
@bwilkerson
Copy link
Member

Are you setting the resolveSupport client configuration data to indicate that these fields can be returned later? More generally, please let us know what client configuration data you're sending to the server.

@DanTup

@DanTup
Copy link
Collaborator

DanTup commented May 21, 2024

Currently, resolve is only used for completion items that are not already imported. For all things currently in-scope, the documentation (and other fields) are included inline. This is one of the things noted at #53501 (I believe there was something that made it non-trivial, but I don't recall the specifics right now).

You can control the level of documentation that is included (here and in hovers) with the dart.documentation configuration setting and you can also reduce the number of items included with the "dart.maxCompletionItems" setting.

@onism0106
Copy link
Author

onism0106 commented May 22, 2024

resolveSupport

yes, I have set the resolveSupport. My capabilities are as follows:

But it still return the documentation field, which is a very large content


Map<String, dynamic> clientCapabilities = {
  "workspace": {
    "applyEdit": true,
    "workspaceEdit": {
      "documentChanges": true,
      "resourceOperations": ["create", "rename", "delete"],
      "failureHandling": "textOnlyTransactional",
      "normalizesLineEndings": true,
      "changeAnnotationSupport": {"groupsOnLabel": true}
    },
    "configuration": true,
    "didChangeWatchedFiles": {
      "dynamicRegistration": true,
      "relativePatternSupport": true
    },
    "symbol": {
      "dynamicRegistration": true,
      "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
        ]
      },
      "tagSupport": {
        "valueSet": [1]
      },
      "resolveSupport": {
        "properties": ["location.range"]
      }
    },
    "codeLens": {"refreshSupport": true},
    "executeCommand": {"dynamicRegistration": true},
    "didChangeConfiguration": {"dynamicRegistration": true},
    "workspaceFolders": true,
    "semanticTokens": {"refreshSupport": true},
    "fileOperations": {
      "dynamicRegistration": true,
      "didCreate": true,
      "didRename": true,
      "didDelete": true,
      "willCreate": true,
      "willRename": true,
      "willDelete": true
    },
    "inlineValue": {"refreshSupport": true},
    "inlayHint": {"refreshSupport": true},
    "diagnostics": {"refreshSupport": true}
  },
  "textDocument": {
    "publishDiagnostics": {
      "relatedInformation": true,
      "versionSupport": false,
      "tagSupport": {
        "valueSet": [1, 2]
      },
      "codeDescriptionSupport": true,
      "dataSupport": true
    },
    "synchronization": {
      "dynamicRegistration": true,
      "willSave": true,
      "willSaveWaitUntil": true,
      "didSave": true
    },
    "completion": {
      "dynamicRegistration": true,
      "contextSupport": true,
      "completionItem": {
        "snippetSupport": true,
        "commitCharactersSupport": true,
        "documentationFormat": ["markdown", "plaintext"],
        "deprecatedSupport": true,
        "preselectSupport": true,
        "tagSupport": {
          "valueSet": [1]
        },
        "insertReplaceSupport": true,
        "resolveSupport": {
          "properties": ["documentation", "detail", "additionalTextEdits"]
        },
        "insertTextModeSupport": {
          "valueSet": [1, 2]
        },
        "labelDetailsSupport": true
      },
      "insertTextMode": 2,
      "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
        ]
      },
      "completionList": {
        "itemDefaults": [
          "commitCharacters",
          "editRange",
          "insertTextFormat",
          "insertTextMode"
        ]
      }
    },
    "hover": {
      "dynamicRegistration": true,
      "contentFormat": ["markdown", "plaintext"]
    },
    "signatureHelp": {
      "dynamicRegistration": true,
      "signatureInformation": {
        "documentationFormat": ["markdown", "plaintext"],
        "parameterInformation": {"labelOffsetSupport": true},
        "activeParameterSupport": true
      },
      "contextSupport": true
    },
    "definition": {"dynamicRegistration": true, "linkSupport": true},
    "references": {"dynamicRegistration": true},
    "documentHighlight": {"dynamicRegistration": true},
    "documentSymbol": {
      "dynamicRegistration": true,
      "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
        ]
      },
      "hierarchicalDocumentSymbolSupport": true,
      "tagSupport": {
        "valueSet": [1]
      },
      "labelSupport": true
    },
    "codeAction": {
      "dynamicRegistration": true,
      "isPreferredSupport": true,
      "disabledSupport": true,
      "dataSupport": true,
      "resolveSupport": {
        "properties": ["edit"]
      },
      "codeActionLiteralSupport": {
        "codeActionKind": {
          "valueSet": [
            "",
            "quickfix",
            "refactor",
            "refactor.extract",
            "refactor.inline",
            "refactor.rewrite",
            "source",
            "source.organizeImports"
          ]
        }
      },
      "honorsChangeAnnotations": false
    },
    "codeLens": {"dynamicRegistration": true},
    "formatting": {"dynamicRegistration": true},
    "rangeFormatting": {"dynamicRegistration": true},
    "onTypeFormatting": {"dynamicRegistration": true},
    "rename": {
      "dynamicRegistration": true,
      "prepareSupport": true,
      "prepareSupportDefaultBehavior": 1,
      "honorsChangeAnnotations": true
    },
    "documentLink": {"dynamicRegistration": true, "tooltipSupport": true},
    "typeDefinition": {"dynamicRegistration": true, "linkSupport": true},
    "implementation": {"dynamicRegistration": true, "linkSupport": true},
    "colorProvider": {"dynamicRegistration": true},
    "foldingRange": {
      "dynamicRegistration": true,
      "rangeLimit": 5000,
      "lineFoldingOnly": true,
      "foldingRangeKind": {
        "valueSet": ["comment", "imports", "region"]
      },
      "foldingRange": {"collapsedText": false}
    },
    "declaration": {"dynamicRegistration": true, "linkSupport": true},
    "selectionRange": {"dynamicRegistration": true},
    "callHierarchy": {"dynamicRegistration": true},
    "semanticTokens": {
      "dynamicRegistration": true,
      "tokenTypes": [
        "namespace",
        "type",
        "class",
        "enum",
        "interface",
        "struct",
        "typeParameter",
        "parameter",
        "variable",
        "property",
        "enumMember",
        "event",
        "function",
        "method",
        "macro",
        "keyword",
        "modifier",
        "comment",
        "string",
        "number",
        "regexp",
        "operator",
        "decorator"
      ],
      "tokenModifiers": [
        "declaration",
        "definition",
        "readonly",
        "static",
        "deprecated",
        "abstract",
        "async",
        "modification",
        "documentation",
        "defaultLibrary"
      ],
      "formats": ["relative"],
      "requests": {
        "range": true,
        "full": {"delta": true}
      },
      "multilineTokenSupport": false,
      "overlappingTokenSupport": false,
      "serverCancelSupport": true,
      "augmentsSyntaxTokens": true
    },
    "linkedEditingRange": {"dynamicRegistration": true},
    "typeHierarchy": {"dynamicRegistration": true},
    "inlineValue": {"dynamicRegistration": true},
    "inlayHint": {
      "dynamicRegistration": true,
      "resolveSupport": {
        "properties": [
          "tooltip",
          "textEdits",
          "label.tooltip",
          "label.location",
          "label.command"
        ]
      }
    },
    "diagnostic": {"dynamicRegistration": true, "relatedDocumentSupport": false}
  },
  "window": {
    "showMessage": {
      "messageActionItem": {"additionalPropertiesSupport": true}
    },
    "showDocument": {"support": true},
    "workDoneProgress": true
  },
  "general": {
    "staleRequestSupport": {
      "cancel": true,
      "retryOnContentModified": [
        "textDocument/semanticTokens/full",
        "textDocument/semanticTokens/range",
        "textDocument/semanticTokens/full/delta"
      ]
    },
    "regularExpressions": {"engine": "ECMAScript", "version": "ES2020"},
    "markdown": {
      "parser": "marked",
      "version": "1.1.0",
      "allowedTags": [
        "ul",
        "li",
        "p",
        "code",
        "blockquote",
        "ol",
        "h1",
        "h2",
        "h3",
        "h4",
        "h5",
        "h6",
        "hr",
        "em",
        "pre",
        "table",
        "thead",
        "tbody",
        "tr",
        "th",
        "td",
        "div",
        "del",
        "a",
        "strong",
        "br",
        "img",
        "span"
      ]
    },
    "positionEncodings": ["utf-16"]
  },
  "notebookDocument": {
    "synchronization": {
      "dynamicRegistration": true,
      "executionSummarySupport": true
    }
  },
  "experimental": {
    "supportsWindowShowMessageRequest": true,
    "snippetTextEdit": true,
    "dartCodeAction": {
      "commandParameterSupport": {
        "supportedKinds": ["saveUri"]
      }
    }
  }
};

@DanTup
Copy link
Collaborator

DanTup commented May 22, 2024

@onism0106 have you tried changing the dart.documentation (or dart.maxCompletionItems) settings noted above?

For now, I think those are the only options that will help here, until we support resolve for the already-in-scope items.

Out of interest - what problem is the payload size causing you? (memory usage? time taken to deserialize json? time to send bytes between server and client?). Is your editor open source?

@DanTup
Copy link
Collaborator

DanTup commented May 22, 2024

I started looking at why we didn't use /resolve for documentation generally and added some notes in #53501 (comment). It was mostly that I was hoping that microsoft/language-server-protocol#1802 would be implemented which would avoid us having to add so much to the payload in order to use /resolve here.

@bwilkerson bwilkerson added analyzer-completion Issues with the analysis server's code completion feature P3 A lower priority bug or feature request labels May 22, 2024
@onism0106
Copy link
Author

@onism0106 have you tried changing the dart.documentation (or dart.maxCompletionItems) settings noted above?

For now, I think those are the only options that will help here, until we support resolve for the already-in-scope items.

Out of interest - what problem is the payload size causing you? (memory usage? time taken to deserialize json? time to send bytes between server and client?). Is your editor open source?

Yes, I am worried about performance issues because there will be frequent interactions with the LSP, each time returning a large amount of data. I am concerned that this might cause performance problems,(memory usage? time taken to deserialize json).

I don't know if my concern is unnecessary.

I'll try set dart.documentation (or dart.maxCompletionItems) later

@DanTup
Copy link
Collaborator

DanTup commented May 24, 2024

If it helps, the payload sizes you're seeing here match what VS Code is dealing with today. I can't be sure the equivalent Dart code performs the same as VS Code's javascript, but hopefully it won't cause any real performance issues.

However, I have pinged on the LSP issue about this, and depending on the response (or lack of), may try to progress something in this area (because there is value in reducing payload sizes for some other situations, like when the extension host/LSP server is on a remote machine).

@DanTup DanTup changed the title textDocument/completion return too many response textDocument/completion payload sizes can be very large because of documentation of in-scope items May 24, 2024
@srawlins srawlins added the type-enhancement A request for a change that isn't a bug label May 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-completion Issues with the analysis server's code completion feature area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P3 A lower priority bug or feature request type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

5 participants