Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions src/services/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2543,16 +2543,20 @@ namespace ts.Completions {
}

if (contextToken.kind === SyntaxKind.GreaterThanToken && contextToken.parent) {
// <Component<string> /**/ />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on its own, this fix makes sense to me. How does it relate to the next comment, which says there are two possibilities -- jsxtext inside a <div> and non-jsxtext inside a type-argument-having <Component<T>? It seems like the second case might be handled entirely by the new code, but I'm not sure.

If it is, then the following check could be simplified.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the same thing, but removing it breaks the test added in the original "don't do completions in JsxText" PR; I can't remember if I figured out why or not at this point, though, so can go double check.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it's the comment that needs to be updated; the second listed possibility is no longer accurate as location in this case isn't GreaterThanToken, it's the entire element. I'll change the comment to reflect that it's only handling the first case.

// <Component<string> /**/ ><Component>
// - contextToken: GreaterThanToken (before cursor)
// - location: JsxSelfClosingElement or JsxOpeningElement
// - contextToken.parent === location
if (location === contextToken.parent && (location.kind === SyntaxKind.JsxOpeningElement || location.kind === SyntaxKind.JsxSelfClosingElement)) {
return false;
}

if (contextToken.parent.kind === SyntaxKind.JsxOpeningElement) {
// Two possibilities:
// 1. <div>/**/
// - contextToken: GreaterThanToken (before cursor)
// - location: JSXElement
// - different parents (JSXOpeningElement, JSXElement)
// 2. <Component<string> /**/>
// - contextToken: GreaterThanToken (before cursor)
// - location: GreaterThanToken (after cursor)
// - same parent (JSXOpeningElement)
// <div>/**/
// - contextToken: GreaterThanToken (before cursor)
// - location: JSXElement
// - different parents (JSXOpeningElement, JSXElement)
return location.parent.kind !== SyntaxKind.JsxOpeningElement;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/// <reference path="fourslash.ts" />
//@Filename: file.tsx

////declare const React: any;
////
////namespace JSX {
//// export interface IntrinsicElements {
//// div: any;
//// }
////}
////
////function GenericElement<T>(props: {xyz?: T}) {
//// return <></>
////}
////
////function fn1() {
//// return <div>
//// <GenericElement<number> /*1*/ />
//// </div>
////}
////
////function fn2() {
//// return <>
//// <GenericElement<number> /*2*/ />
//// </>
////}
////function fn3() {
//// return <div>
//// <GenericElement<number> /*3*/ ></GenericElement>
//// </div>
////}
////
////function fn4() {
//// return <>
//// <GenericElement<number> /*4*/ ></GenericElement>
//// </>
////}

verify.completions(
{
marker: test.markers(),
includes: {
name: "xyz",
insertText: "xyz={$1}",
text: "(property) xyz?: number",
isSnippet: true,
sortText: completion.SortText.OptionalMember
},
preferences: {
jsxAttributeCompletionStyle: "braces",
includeCompletionsWithSnippetText: true,
includeCompletionsWithInsertText: true,
},
},
)