diff --git a/src/services/completions.ts b/src/services/completions.ts index c6d5f015279..1aac8cd2c68 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -862,6 +862,23 @@ namespace ts.Completions { parent = parent.parent; } + // Fix location + if (currentToken.parent === location) { + switch (currentToken.kind) { + case SyntaxKind.GreaterThanToken: + if (currentToken.parent.kind === SyntaxKind.JsxElement || currentToken.parent.kind === SyntaxKind.JsxOpeningElement) { + location = currentToken; + } + break; + + case SyntaxKind.SlashToken: + if (currentToken.parent.kind === SyntaxKind.JsxSelfClosingElement) { + location = currentToken; + } + break; + } + } + switch (parent.kind) { case SyntaxKind.JsxClosingElement: if (contextToken.kind === SyntaxKind.SlashToken) { @@ -1042,10 +1059,6 @@ namespace ts.Completions { return true; } - if (tryGetFunctionLikeBodyCompletionContainer(contextToken)) { - keywordFilters = KeywordCompletionFilters.FunctionLikeBodyKeywords; - } - if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) { // cursor inside class declaration getGetClassLikeCompletionSymbols(classLikeContainer); @@ -1067,6 +1080,10 @@ namespace ts.Completions { } } + if (tryGetFunctionLikeBodyCompletionContainer(contextToken)) { + keywordFilters = KeywordCompletionFilters.FunctionLikeBodyKeywords; + } + // Get all entities in the current scope. completionKind = CompletionKind.None; isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken); diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 9ec99f6ccaf..387d027d999 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -79,6 +79,8 @@ namespace ts.SymbolDisplay { switch (location.parent && location.parent.kind) { // If we've typed a character of the attribute name, will be 'JsxAttribute', else will be 'JsxOpeningElement'. case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxElement: + case SyntaxKind.JsxSelfClosingElement: return location.kind === SyntaxKind.Identifier ? ScriptElementKind.memberVariableElement : ScriptElementKind.jsxAttribute; case SyntaxKind.JsxAttribute: return ScriptElementKind.jsxAttribute; diff --git a/tests/cases/fourslash/completionsInJsxTag.ts b/tests/cases/fourslash/completionsInJsxTag.ts new file mode 100644 index 00000000000..a38f64e8fed --- /dev/null +++ b/tests/cases/fourslash/completionsInJsxTag.ts @@ -0,0 +1,27 @@ +/// + +// @jsx: preserve + +// @Filename: /a.tsx +////declare namespace JSX { +//// interface Element {} +//// interface IntrinsicElements { +//// div: { +//// /** Doc */ +//// foo: string +//// } +//// } +////} +////class Foo { +//// render() { +////
; +////
+//// } +////} + +goTo.marker("1"); +verify.completionListCount(1); +verify.completionListContains("foo", "(JSX attribute) foo: string", "Doc ", "JSX attribute"); +goTo.marker("2"); +verify.completionListCount(1); +verify.completionListContains("foo", "(JSX attribute) foo: string", "Doc ", "JSX attribute");