Skip to content

Commit 940d165

Browse files
authored
Merge pull request microsoft#14212 from Microsoft/master-12989
[Master] Fix 12989: completion in JSX opening-like element when tag name is a property access expression
2 parents 8817703 + 0290e20 commit 940d165

File tree

2 files changed

+59
-6
lines changed

2 files changed

+59
-6
lines changed

src/services/completions.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,8 @@ namespace ts.Completions {
447447
return undefined;
448448
}
449449

450-
const { parent, kind } = contextToken;
451-
if (kind === SyntaxKind.DotToken) {
450+
let parent = contextToken.parent;
451+
if (contextToken.kind === SyntaxKind.DotToken) {
452452
if (parent.kind === SyntaxKind.PropertyAccessExpression) {
453453
node = (<PropertyAccessExpression>contextToken.parent).expression;
454454
isRightOfDot = true;
@@ -464,16 +464,24 @@ namespace ts.Completions {
464464
}
465465
}
466466
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
467-
switch (contextToken.parent.kind) {
467+
// <UI.Test /* completion position */ />
468+
// If the tagname is a property access expression, we will then walk up to the top most of property access expression.
469+
// Then, try to get a JSX container and its associated attributes type.
470+
if (parent && parent.kind === SyntaxKind.PropertyAccessExpression) {
471+
contextToken = parent;
472+
parent = parent.parent;
473+
}
474+
475+
switch (parent.kind) {
468476
case SyntaxKind.JsxClosingElement:
469-
if (kind === SyntaxKind.SlashToken) {
477+
if (contextToken.kind === SyntaxKind.SlashToken) {
470478
isStartingCloseTag = true;
471479
location = contextToken;
472480
}
473481
break;
474482

475483
case SyntaxKind.BinaryExpression:
476-
if (!((contextToken.parent as BinaryExpression).left.flags & NodeFlags.ThisNodeHasError)) {
484+
if (!((parent as BinaryExpression).left.flags & NodeFlags.ThisNodeHasError)) {
477485
// It has a left-hand side, so we're not in an opening JSX tag.
478486
break;
479487
}
@@ -482,7 +490,7 @@ namespace ts.Completions {
482490
case SyntaxKind.JsxSelfClosingElement:
483491
case SyntaxKind.JsxElement:
484492
case SyntaxKind.JsxOpeningElement:
485-
if (kind === SyntaxKind.LessThanToken) {
493+
if (contextToken.kind === SyntaxKind.LessThanToken) {
486494
isRightOfOpenTag = true;
487495
location = contextToken;
488496
}
@@ -950,6 +958,7 @@ namespace ts.Completions {
950958
case SyntaxKind.LessThanSlashToken:
951959
case SyntaxKind.SlashToken:
952960
case SyntaxKind.Identifier:
961+
case SyntaxKind.PropertyAccessExpression:
953962
case SyntaxKind.JsxAttributes:
954963
case SyntaxKind.JsxAttribute:
955964
case SyntaxKind.JsxSpreadAttribute:
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/// <reference path='fourslash.ts' />
2+
//@module: commonjs
3+
//@jsx: preserve
4+
5+
//// declare module JSX {
6+
//// interface Element { }
7+
//// interface IntrinsicElements {
8+
//// }
9+
//// interface ElementAttributesProperty { props; }
10+
//// }
11+
12+
//@Filename: exporter.tsx
13+
//// export class Thing { props: { ONE: string; TWO: number } }
14+
//// export module M {
15+
//// export declare function SFCComp(props: { Three: number; Four: string }): JSX.Element;
16+
//// }
17+
18+
//@Filename: file.tsx
19+
//// import * as Exp from './exporter';
20+
//// var x1 = <Exp.Thing /*1*/ />;
21+
//// var x2 = <Exp.M.SFCComp /*2*/ />;
22+
//// var x3 = <Exp.Thing /*3*/ ></Exp.Thing>;
23+
//// var x4 = <Exp.M.SFCComp /*4*/ ></Exp.M.SFCComp>;
24+
25+
26+
goTo.marker("1");
27+
verify.completionListCount(2);
28+
verify.completionListContains('ONE');
29+
verify.completionListContains('TWO');
30+
31+
goTo.marker("2");
32+
verify.completionListCount(2);
33+
verify.completionListContains("Three");
34+
verify.completionListContains("Four");
35+
36+
goTo.marker("3");
37+
verify.completionListCount(2);
38+
verify.completionListContains('ONE');
39+
verify.completionListContains('TWO');
40+
41+
goTo.marker("4");
42+
verify.completionListCount(2);
43+
verify.completionListContains("Three");
44+
verify.completionListContains("Four");

0 commit comments

Comments
 (0)