Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
3 changes: 2 additions & 1 deletion src/services/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2898,7 +2898,8 @@ function getCompletionData(
// First case is for `<div foo={true} [||] />` or `<div foo={true} [||] ></div>`,
// `parent` will be `{true}` and `previousToken` will be `}`
// Second case is for `<div foo={true} t[||] ></div>`
if (previousToken.kind === SyntaxKind.CloseBraceToken || (previousToken.kind === SyntaxKind.Identifier || previousToken.parent.kind === SyntaxKind.JsxAttribute)) {
// Second case must not match for `<div foo={undefine[||]}></div>`
if (previousToken.kind === SyntaxKind.CloseBraceToken || (previousToken.kind === SyntaxKind.Identifier && previousToken.parent.kind === SyntaxKind.JsxAttribute)) {
isJsxIdentifierExpected = true;
}
break;
Expand Down
1 change: 1 addition & 0 deletions src/testRunner/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ import "./unittests/tsserver/cancellationToken";
import "./unittests/tsserver/compileOnSave";
import "./unittests/tsserver/completions";
import "./unittests/tsserver/completionsIncomplete";
import "./unittests/tsserver/completionsJsxExpression";
import "./unittests/tsserver/configFileSearch";
import "./unittests/tsserver/configuredProjects";
import "./unittests/tsserver/declarationFileMaps";
Expand Down
60 changes: 60 additions & 0 deletions src/testRunner/unittests/tsserver/completionsJsxExpression.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as ts from "../../_namespaces/ts";
import {
createServerHost,
} from "../virtualFileSystemWithWatch";
import {
baselineTsserverLogs,
createLoggerWithInMemoryLogs,
createSession,
} from "./helpers";

describe("unittests:: tsserver:: completionsJsxExpression", () => {
it("should not error", () => {
const host = createServerHost([]);
const session = createSession(host, {
canUseEvents: true,
noGetErrOnBackgroundUpdate: true,
logger: createLoggerWithInMemoryLogs(host),
});
session.executeCommandSeq<ts.server.protocol.ConfigureRequest>({
command: ts.server.protocol.CommandTypes.Configure,
arguments: {
preferences: {
jsxAttributeCompletionStyle: "auto",
includeCompletionsWithSnippetText: true,
}
}
});
session.executeCommandSeq<ts.server.protocol.UpdateOpenRequest>({
command: ts.server.protocol.CommandTypes.UpdateOpen,
arguments: {
changedFiles: [],
closedFiles: [],
openFiles: [
{
file: "^/untitled/ts-nul-authority/Untitled-1",
fileContent: `interface IntrinsicElements { div: { foo?: number } }\n<div foo={undefine}></div>`,
scriptKindName: "TSX"
}
]
}
});
const completion = session.executeCommandSeq<ts.server.protocol.CompletionsRequest>({
command: ts.server.protocol.CommandTypes.CompletionInfo,
arguments: {
file: "^/untitled/ts-nul-authority/Untitled-1",
line: 2,
offset: 19,
includeInsertTextCompletions: true,
}
}).response as ts.server.protocol.CompletionInfo | undefined;
baselineTsserverLogs("completionsJsxExpression", "should not complete as jsx attribute", session);
ts.Debug.assertIsDefined(completion);
for (const entry of completion.entries) {
ts.Debug.assert(!entry.isSnippet);
if (entry.insertText) {
ts.Debug.assert(!entry.insertText.includes("="));
}
}
});
});
Loading