JSX closing tag completion: Include '>' if not already present (#25551)

* JSX closing tag completion: Include '>' if not already present

* Expand comment
This commit is contained in:
Andy 2018-07-10 16:14:57 -07:00 committed by GitHub
parent 527093c758
commit 7a79a45aab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 19 additions and 25 deletions

View file

@ -111,20 +111,22 @@ namespace ts.Completions {
function completionInfoFromData(sourceFile: SourceFile, typeChecker: TypeChecker, compilerOptions: CompilerOptions, log: Log, completionData: CompletionData, preferences: UserPreferences): CompletionInfo | undefined {
const { symbols, completionKind, isInSnippetScope, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, literals, symbolToOriginInfoMap, recommendedCompletion, isJsxInitializer } = completionData;
if (sourceFile.languageVariant === LanguageVariant.JSX && location && location.parent && isJsxClosingElement(location.parent)) {
if (location && location.parent && isJsxClosingElement(location.parent)) {
// In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag,
// instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element.
// For example:
// var x = <div> </ /*1*/>
// The completion list at "1" will contain "div" with type any
// var x = <div> </ /*1*/
// The completion list at "1" will contain "div>" with type any
// And at `<div> </ /*1*/ >` (with a closing `>`), the completion list will contain "div".
const tagName = location.parent.parent.openingElement.tagName;
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false,
entries: [{
name: tagName.getFullText(),
kind: ScriptElementKind.classElement,
kindModifiers: undefined,
sortText: "0",
}]};
const hasClosingAngleBracket = !!findChildOfKind(location.parent, SyntaxKind.GreaterThanToken, sourceFile);
const entry: CompletionEntry = {
name: tagName.getFullText(sourceFile) + (hasClosingAngleBracket ? "" : ">"),
kind: ScriptElementKind.classElement,
kindModifiers: undefined,
sortText: "0",
};
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [entry] };
}
const entries: CompletionEntry[] = [];

View file

@ -42,7 +42,7 @@ verify.completions(
{ marker: "openTag", includes: "div", triggerCharacter: "<" },
{ marker: "lessThan", exact: undefined, triggerCharacter: "<" },
{ marker: "closeTag", exact: "div", triggerCharacter: "/" },
{ marker: "closeTag", exact: "div>", triggerCharacter: "/" },
{ marker: "path", exact: "importMe", triggerCharacter: "/", isNewIdentifierLocation: true },
{ marker: "divide", exact: undefined, triggerCharacter: "/" },
);

View file

@ -6,10 +6,8 @@
//// export var Foo: any = null;
//// }
//// const j = <NS.Foo>Hello!/**/
////
////
goTo.marker();
edit.insert("</");
verify.completionListContains("NS.Foo");
verify.not.completionListContains("Foo");
verify.completionListCount(1);
verify.completions({ exact: "NS.Foo>" });

View file

@ -9,6 +9,4 @@
//// }
//// var x1 = <div><//**/
goTo.marker();
verify.completionListCount(1);
verify.completionListContains('div');
verify.completions({ marker: "", exact: "div>" });

View file

@ -9,6 +9,4 @@
//// }
//// var x1 = <div><//**/
goTo.marker();
verify.completionListCount(1);
verify.completionListContains('div');
verify.completions({ marker: "", exact: "div>" });

View file

@ -3,6 +3,4 @@
//@Filename: file.tsx
//// var x1 = <div><//**/
goTo.marker();
verify.completionListCount(1);
verify.completionListContains('div');
verify.completions({ marker: "", exact: "div>" });

View file

@ -5,4 +5,4 @@
//// <h1> Hello world </ /*2*/>
//// </ /*1*/>
verify.completions({ marker: "1", exact: ["div"] }, { marker: "2", exact: ["h1"] });
verify.completions({ marker: "1", exact: "div" }, { marker: "2", exact: "h1" });