microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.14k stars 12.5k forks source link

JavaScript intellisence shows Date.parse() description for function JSON.parse() when signature help is automatically invoked during surrounding of argument with both parentheses simultaneously #48428

Open rioj7 opened 2 years ago

rioj7 commented 2 years ago

Does this issue occur when all extensions are disabled?: Yes

Steps to Reproduce:

  1. Create a JavaScript file with the following content
    function foobar(value) {
    let json = JSON.parsevalue;
    }
  2. The () are missing for the parse call on line 2
  3. Select the text value and type ( to surround it with () and fix the syntax error
  4. VSCode now shows the following function tooltip:
    
    JSON.parse(s: string): number
    A date string

Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970.



This is the text for the function `Date.parse(s: string)`. It even uses the parameter name `s` instead of `text` that is shown in the correct tooltip for `JSON.parse(text:string, reviver?:.....)`
mjbvz commented 2 years ago

I'm having trouble reproducing this. In step 2, does the description text show up automatically when you type (? Or do you have to do something else to trigger this?

mjbvz commented 2 years ago

Also please test using the latest VS Code build. You are currently on an old one

rioj7 commented 2 years ago

@mjbvz

I have just updated my Insider version (no settings and no extensions installed)

Version: 1.66.0-insider (user setup)
Commit: c63ed49b4b164210301f4f8a09079aa4de53b870
Date: 2022-03-25T14:30:54.397Z

I have the same behavior, the tooltip appears automatic.

Is the text of these tooltips part of VSCode or are they downloaded after the install/update.

Can they be shared between my VSCode and VSCode Insider installs.

MartinJohns commented 2 years ago

What TypeScript version do you have installed? Do you have a jsconfig file? Do you have any packages installed?

I can't reproduce the issue either, and it already fails with the first step: I'm not getting a syntax error from the code you posted.

rioj7 commented 2 years ago

@MartinJohns

IllusionMH commented 2 years ago

I was able to reproduce it in VS Code Insiders with typesctipt@next, so it is not because of the old versions, but requires following exact steps from OP.

rioj7 commented 2 years ago

@IllusionMH I'm unfamiliar with typesctipt@next, can you explain it a bit

MartinJohns commented 2 years ago

@IllusionMH Can't reproduce it with VS Code Insiders (1.66.0, commit 10dc49b) and TypeScript nightly (4.7.0-dev.20220327) running in WSL2. Weird issue.

IllusionMH commented 2 years ago

I'm on Windows (not in WSL1/2) with same versions Version: 1.66.0-insider (user setup) Commit: 10dc49b279e2f8ab0194a0e831ade4ea773b8a55 Date: 2022-03-27T12:24:07.686Z OS: Windows_NT x64 10.0.19043

TypeScript: 4.7.0-dev.20220327

tsserver.log Log is for Untitled file, however reproducible in saved file as well.


The problem is with call to signatureHelp command

It's triggered automatically when I select value from parsevalue and press (

Lines 657-677 (triggerReason is characterTyped)

Info 114  [17:02:36.339] request:
    {
      "seq": 26,
      "type": "request",
      "command": "signatureHelp",
      "arguments": {
        "file": "^/untitled/Untitled-1",
        "line": 2,
        "offset": 32,
        "triggerReason": {
          "kind": "characterTyped",
          "triggerCharacter": "("
        }
      }
    }
Info 115  [17:02:36.339] Starting updateGraphWorker: Project: /dev/null/inferredProject1*
Info 116  [17:02:36.344] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 2 structureChanged: false structureIsReused:: Completely Elapsed: 4.909199953079224ms
Info 117  [17:02:36.344] Different program with same set of files
Perf 118  [17:02:36.351] 26::signatureHelp: elapsed time (in milliseconds) 11.9625
Info 119  [17:02:36.351] response:
    {"seq":0,"type":"response","command":"signatureHelp","request_seq":26,"success":true,"performanceData":{"updateGraphDurationMs":4.909199953079224},"body":{"items":[{"isVariadic":false,"prefixDisplayParts":[{"text":"JSON","kind":"localName"},{"text":".","kind":"punctuation"},{"text":"parse","kind":"methodName"},{"text":"(","kind":"punctuation"}],"suffixDisplayParts":[{"text":")","kind":"punctuation"},{"text":":","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"number","kind":"keyword"}],"separatorDisplayParts":[{"text":",","kind":"punctuation"},{"text":" ","kind":"space"}],"parameters":[{"name":"s","documentation":[{"text":"A date string","kind":"text"}],"displayParts":[{"text":"s","kind":"parameterName"},{"text":":","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"string","kind":"keyword"}],"isOptional":false,"isRest":false}],"documentation":[{"text":"Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970.","kind":"text"}],"tags":[{"name":"param","text":[{"text":"s","kind":"parameterName"},{"text":" ","kind":"space"},{"text":"A date string","kind":"text"}]}]}],"applicableSpan":{"start":{"line":2,"offset":27},"end":{"line":2,"offset":32}},"selectedItemIndex":0,"argumentIndex":0,"argumentCount":1}}

however no problems later even if it's manually triggered in same position Lines 1061-1077 (triggerReason is invoked)

Info 201  [17:03:10.047] request:
    {
      "seq": 51,
      "type": "request",
      "command": "signatureHelp",
      "arguments": {
        "file": "^/untitled/Untitled-1",
        "line": 2,
        "offset": 32,
        "triggerReason": {
          "kind": "invoked"
        }
      }
    }
Perf 202  [17:03:10.049] 51::signatureHelp: elapsed time (in milliseconds) 2.3334
Info 203  [17:03:10.049] response:
    {"seq":0,"type":"response","command":"signatureHelp","request_seq":51,"success":true,"body":{"items":[{"isVariadic":false,"prefixDisplayParts":[{"text":"parse","kind":"methodName"},{"text":"(","kind":"punctuation"}],"suffixDisplayParts":[{"text":")","kind":"punctuation"},{"text":":","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"any","kind":"keyword"}],"separatorDisplayParts":[{"text":",","kind":"punctuation"},{"text":" ","kind":"space"}],"parameters":[{"name":"text","documentation":[{"text":"A valid JSON string.","kind":"text"}],"displayParts":[{"text":"text","kind":"parameterName"},{"text":":","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"string","kind":"keyword"}],"isOptional":false,"isRest":false},{"name":"reviver","documentation":[{"text":"A function that transforms the results. This function is called for each member of the object.\r\nIf a member contains nested objects, the nested objects are transformed before the parent object is.","kind":"text"}],"displayParts":[{"text":"reviver","kind":"parameterName"},{"text":"?","kind":"punctuation"},{"text":":","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"(","kind":"punctuation"},{"text":"this","kind":"parameterName"},{"text":":","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"any","kind":"keyword"},{"text":",","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"key","kind":"parameterName"},{"text":":","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"string","kind":"keyword"},{"text":",","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"value","kind":"parameterName"},{"text":":","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"any","kind":"keyword"},{"text":")","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"=>","kind":"punctuation"},{"text":" ","kind":"space"},{"text":"any","kind":"keyword"}],"isOptional":true,"isRest":false}],"documentation":[{"text":"Converts a JavaScript Object Notation (JSON) string into an object.","kind":"text"}],"tags":[{"name":"param","text":[{"text":"text","kind":"parameterName"},{"text":" ","kind":"space"},{"text":"A valid JSON string.","kind":"text"}]},{"name":"param","text":[{"text":"reviver","kind":"parameterName"},{"text":" ","kind":"space"},{"text":"A function that transforms the results. This function is called for each member of the object.\r\nIf a member contains nested objects, the nested objects are transformed before the parent object is.","kind":"text"}]}]}],"applicableSpan":{"start":{"line":2,"offset":27},"end":{"line":2,"offset":32}},"selectedItemIndex":0,"argumentIndex":0,"argumentCount":1}}

UPD. @rioj7 typescript@next is npm tag that points to nightly version of TS

rioj7 commented 2 years ago

@IllusionMH thanks for typescript@next explanation,

These temporary repo files https://github.com/user_name/repo_name/files/9999999/tsserver.log is this a feature for all repositories. If I do a search I only get Upload files to be committed pages.

Are these from Attach files by dragging? I was unaware the issue was transferred to Typescript.

RyanCavanaugh commented 2 years ago

I haven't debugged, but reading the log, VS Code is sending us this request

        "line": 2,
        "offset": 32,
        "triggerReason": {
          "kind": "characterTyped",
          "triggerCharacter": "("
        }

But offset 32 is the closing paren ). I don't know if that's the problem, but it's a weird way to get the request

IllusionMH commented 2 years ago

This is where cursor is when user selects value left to right and remains there when selection is wrapped in parens. Result looks like .parse(value|) (value remains selected) and signature help is requested without any additional user action.

Manually triggering signnature help in that position works OK.

I think triggering signature help in that position is logical if you just finished typing first parameter and would like to see what are other params.

I can't post video ATM.


@rioj7 it just file uploaded to comment.