Merge pull request #32243 from orta/fix-30536

Adds support for class completions after ASI inserted class property definition
This commit is contained in:
Orta 2019-07-15 11:54:13 -04:00 committed by GitHub
commit 2c26ac2e43
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 6 deletions

View file

@ -1617,7 +1617,7 @@ namespace ts.Completions {
* Relevant symbols are stored in the captured 'symbols' variable.
*/
function tryGetClassLikeCompletionSymbols(): GlobalsSearch {
const decl = tryGetObjectTypeDeclarationCompletionContainer(sourceFile, contextToken, location);
const decl = tryGetObjectTypeDeclarationCompletionContainer(sourceFile, contextToken, location, position);
if (!decl) return GlobalsSearch.Continue;
// We're looking up possible property names from parent type.
@ -2234,7 +2234,7 @@ namespace ts.Completions {
* Returns the immediate owning class declaration of a context token,
* on the condition that one exists and that the context implies completion should be given.
*/
function tryGetObjectTypeDeclarationCompletionContainer(sourceFile: SourceFile, contextToken: Node | undefined, location: Node): ObjectTypeDeclaration | undefined {
function tryGetObjectTypeDeclarationCompletionContainer(sourceFile: SourceFile, contextToken: Node | undefined, location: Node, position: number): ObjectTypeDeclaration | undefined {
// class c { method() { } | method2() { } }
switch (location.kind) {
case SyntaxKind.SyntaxList:
@ -2244,9 +2244,15 @@ namespace ts.Completions {
if (cls && !findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile)) {
return cls;
}
break;
case SyntaxKind.Identifier: // class c extends React.Component { a: () => 1\n compon| }
if (isFromObjectTypeDeclaration(location)) {
return findAncestor(location, isObjectTypeDeclaration);
}
}
if (!contextToken) return undefined;
switch (contextToken.kind) {
case SyntaxKind.SemicolonToken: // class c {getValue(): number; | }
case SyntaxKind.CloseBraceToken: // class c { method() { } | }
@ -2258,7 +2264,13 @@ namespace ts.Completions {
case SyntaxKind.CommaToken: // class c {getValue(): number, | }
return tryCast(contextToken.parent, isObjectTypeDeclaration);
default:
if (!isFromObjectTypeDeclaration(contextToken)) return undefined;
if (!isFromObjectTypeDeclaration(contextToken)) {
// class c extends React.Component { a: () => 1\n| }
if (getLineAndCharacterOfPosition(sourceFile, contextToken.getEnd()).line !== getLineAndCharacterOfPosition(sourceFile, position).line && isObjectTypeDeclaration(location)) {
return location;
}
return undefined;
}
const isValidKeyword = isClassLike(contextToken.parent.parent) ? isClassMemberCompletionKeyword : isInterfaceOrTypeLiteralCompletionKeyword;
return (isValidKeyword(contextToken.kind) || contextToken.kind === SyntaxKind.AsteriskToken || isIdentifier(contextToken) && isValidKeyword(stringToToken(contextToken.text)!)) // TODO: GH#18217
? contextToken.parent.parent as ObjectTypeDeclaration : undefined;

View file

@ -892,7 +892,7 @@ namespace ts {
}
export interface CompletionInfo {
/** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isSnippetScope`. */
/** Not true for all global completions. This will be true if the enclosing scope matches a few syntax kinds. See `isSnippetScope`. */
isGlobalCompletion: boolean;
isMemberCompletion: boolean;

View file

@ -5404,7 +5404,7 @@ declare namespace ts {
argumentCount: number;
}
interface CompletionInfo {
/** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isSnippetScope`. */
/** Not true for all global completions. This will be true if the enclosing scope matches a few syntax kinds. See `isSnippetScope`. */
isGlobalCompletion: boolean;
isMemberCompletion: boolean;
/**

View file

@ -5404,7 +5404,7 @@ declare namespace ts {
argumentCount: number;
}
interface CompletionInfo {
/** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isSnippetScope`. */
/** Not true for all global completions. This will be true if the enclosing scope matches a few syntax kinds. See `isSnippetScope`. */
isGlobalCompletion: boolean;
isMemberCompletion: boolean;
/**

View file

@ -0,0 +1,21 @@
/// <reference path='fourslash.ts'/>
//// class Parent {
//// protected shouldWork() {
//// console.log();
//// }
//// }
////
//// class Child extends Parent {
//// // this assumes ASI, but on next line wants to
//// x = () => 1
//// shoul/*insideid*/
//// }
////
//// class ChildTwo extends Parent {
//// // this assumes ASI, but on next line wants to
//// x = () => 1
//// /*root*/ //nothing
//// }
verify.completions({ marker: ["insideid", "root"], includes: "shouldWork", isNewIdentifierLocation: true });