Repository navigation
Assertion failure in method snippet completions for subclasses with multiple type parameter references #48379
Copy link
Copy link
Closed
Labels
BugA bug in TypeScriptA bug in TypeScriptCrashFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad outputFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad outputDomain: LS: Completion ListsThe issue relates to showing completion lists in an editorThe issue relates to showing completion lists in an editorFix AvailableA PR has been opened for this issueA PR has been opened for this issue
Milestone
Description
Same stack trace as #45744
declare class Component<T> {
setState(stateHandler: ((oldState: T, newState: T) => void)): void;
}
class SubComponent extends Component<{}> {
/*$*/
}Request snippet completions at /*$*/.
<semantic> Response received: completionInfo (1916). Request took 8 ms. Success: false . Message: Error processing request. Debug Failure. False expression.
Error: Debug Failure. False expression.
at consumeTokenAndAdvanceScanner ([node_modules_dir]/typescript/lib/tsserver.js:145519:30)
at processChildNodes ([node_modules_dir]/typescript/lib/tsserver.js:145489:33)
at [node_modules_dir]/typescript/lib/tsserver.js:145384:21
at visitNodes ([node_modules_dir]/typescript/lib/tsserver.js:30152:24)
at Object.forEachChild ([node_modules_dir]/typescript/lib/tsserver.js:30323:24)
at processNode ([node_modules_dir]/typescript/lib/tsserver.js:145381:20)
at processChildNode ([node_modules_dir]/typescript/lib/tsserver.js:145449:21)
at processChildNodes ([node_modules_dir]/typescript/lib/tsserver.js:145496:48)
at [node_modules_dir]/typescript/lib/tsserver.js:145384:21
at visitNodes ([node_modules_dir]/typescript/lib/tsserver.js:30152:24)
at Object.forEachChild ([node_modules_dir]/typescript/lib/tsserver.js:30330:24)
at processNode ([node_modules_dir]/typescript/lib/tsserver.js:145381:20)
at processChildNode ([node_modules_dir]/typescript/lib/tsserver.js:145449:21)
at [node_modules_dir]/typescript/lib/tsserver.js:145382:21
at visitNode ([node_modules_dir]/typescript/lib/tsserver.js:30147:24)
at Object.forEachChild ([node_modules_dir]/typescript/lib/tsserver.js:30242:21)
at processNode ([node_modules_dir]/typescript/lib/tsserver.js:145381:20)
at processChildNode ([node_modules_dir]/typescript/lib/tsserver.js:145449:21)
at processChildNodes ([node_modules_dir]/typescript/lib/tsserver.js:145496:48)
at [node_modules_dir]/typescript/lib/tsserver.js:145384:21
at visitNodes ([node_modules_dir]/typescript/lib/tsserver.js:30152:24)
at Object.forEachChild ([node_modules_dir]/typescript/lib/tsserver.js:30304:21)
at processNode ([node_modules_dir]/typescript/lib/tsserver.js:145381:20)
at formatSpanWorker ([node_modules_dir]/typescript/lib/tsserver.js:145182:17)
at [node_modules_dir]/typescript/lib/tsserver.js:145146:140
at Object.getFormattingScanner ([node_modules_dir]/typescript/lib/tsserver.js:143773:23)
at Object.formatNodeGivenIndentation ([node_modules_dir]/typescript/lib/tsserver.js:145146:31)
at [node_modules_dir]/typescript/lib/tsserver.js:131006:46
at Object.flatMap ([node_modules_dir]/typescript/lib/tsserver.js:508:25)
at getEntryForMemberCompletion ([node_modules_dir]/typescript/lib/tsserver.js:131004:38)
at createCompletionEntry ([node_modules_dir]/typescript/lib/tsserver.js:130828:23)
at getCompletionEntriesFromSymbols ([node_modules_dir]/typescript/lib/tsserver.js:131194:29)
at completionInfoFromData ([node_modules_dir]/typescript/lib/tsserver.js:130646:17)
at Object.getCompletionsAtPosition ([node_modules_dir]/typescript/lib/tsserver.js:130507:36)
at Object.getCompletionsAtPosition ([node_modules_dir]/typescript/lib/tsserver.js:163069:35)
at IpcIOSession.Session.getCompletions ([node_modules_dir]/typescript/lib/tsserver.js:174630:64)
at Session.handlers.ts.Map.ts.getEntries._a.<computed> ([node_modules_dir]/typescript/lib/tsserver.js:173451:61)
at [node_modules_dir]/typescript/lib/tsserver.js:175346:88
at IpcIOSession.Session.executeWithRequestId ([node_modules_dir]/typescript/lib/tsserver.js:175337:28)
at IpcIOSession.Session.executeCommand ([node_modules_dir]/typescript/lib/tsserver.js:175346:33)
at IpcIOSession.Session.onMessage ([node_modules_dir]/typescript/lib/tsserver.js:175372:35)
at process.<anonymous> ([node_modules_dir]/typescript/lib/tsserver.js:178007:31)
at process.emit (events.js:315:20)
at emit (internal/child_process.js:903:12)
at processTicksAndRejections (internal/process/task_queues.js:81:21)
That's one minimal example. The more motivating example is completion for all React class components.
interface Component<P = {}, S = {}, SS = any> { }
declare class Component<P, S> {
setState<K extends keyof S>(
state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
callback?: () => void
): void;
}
export class Thing extends Component<{}> {
/*$*/
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScriptCrashFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad outputFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad outputDomain: LS: Completion ListsThe issue relates to showing completion lists in an editorThe issue relates to showing completion lists in an editorFix AvailableA PR has been opened for this issueA PR has been opened for this issue
Activity
[-]Assertion failure in method snippet completions for subclasses from React's setState[/-][+]Assertion failure in method snippet completions for subclasses with multiple type parameter references[/+]jakebailey commentedon Mar 28, 2022
I think I've wrapped my head around this one.
In the above example, the key is that in the real method implementation, the type var appears more than once. All of the
Ts need to be converted to{}, except that all{}nodes in this tree appear to be the same object. This trips up the text change code, as when the new text (with{}) is being created, the walker stores the new positions onto the node, so that later those nodes can use the faked SourceFile with the new text. But since all of the{}s are the same node, the position ends up being wherever the last walked{}is, which breaks the invariant that a node's children actually be within its range.jakebailey commentedon Mar 28, 2022
Hm, maybe not; I forced the node constructor to add unique IDs to each node and they are different. Back to debugging, I guess.
jakebailey commentedon Mar 29, 2022
No, I was right initially. Here's the emitter going over the second empty type literal, but the
membersNodeArray is the same and already has the side-effect__posand__endset.DanielRosenwasser commentedon Mar 30, 2022
I wonder if this also fixes #48405 at all?
jakebailey commentedon Mar 30, 2022
That issue already has #48481 (which is unreviewed) and looks different. I'll check the test case on main and see, though.