mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-20 22:51:17 -05:00
Give the class element completion on typing keywords like public, private, readonly
Also when name of the function is location, make sure we are actually looking at the same symbol before using the declaration to get signature to display
This commit is contained in:
@@ -988,6 +988,10 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isFromClassElementDeclaration(node: Node) {
|
||||
return isClassElement(node.parent) && isClassLike(node.parent.parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -1010,6 +1014,13 @@ namespace ts.Completions {
|
||||
return location;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isFromClassElementDeclaration(contextToken) &&
|
||||
(isClassMemberCompletionKeyword(contextToken.kind) ||
|
||||
isClassMemberCompletionKeywordText(contextToken.getText()))) {
|
||||
return contextToken.parent.parent as ClassLikeDeclaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,7 +1159,7 @@ namespace ts.Completions {
|
||||
isFunction(containingNodeKind);
|
||||
|
||||
case SyntaxKind.StaticKeyword:
|
||||
return containingNodeKind === SyntaxKind.PropertyDeclaration;
|
||||
return containingNodeKind === SyntaxKind.PropertyDeclaration && !isClassLike(contextToken.parent.parent);
|
||||
|
||||
case SyntaxKind.DotDotDotToken:
|
||||
return containingNodeKind === SyntaxKind.Parameter ||
|
||||
@@ -1165,13 +1176,17 @@ namespace ts.Completions {
|
||||
containingNodeKind === SyntaxKind.ExportSpecifier ||
|
||||
containingNodeKind === SyntaxKind.NamespaceImport;
|
||||
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
if (isFromClassElementDeclaration(contextToken)) {
|
||||
return false;
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.LetKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
@@ -1180,6 +1195,13 @@ namespace ts.Completions {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the previous token is keyword correspoding to class member completion keyword
|
||||
// there will be completion available here
|
||||
if (isClassMemberCompletionKeywordText(contextToken.getText()) &&
|
||||
isFromClassElementDeclaration(contextToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Previous token may have been a keyword that was converted to an identifier.
|
||||
switch (contextToken.getText()) {
|
||||
case "abstract":
|
||||
@@ -1373,8 +1395,8 @@ namespace ts.Completions {
|
||||
});
|
||||
}
|
||||
|
||||
const classMemberKeywordCompletions = filter(keywordCompletions, entry => {
|
||||
switch (stringToToken(entry.name)) {
|
||||
function isClassMemberCompletionKeyword(kind: SyntaxKind) {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
@@ -1386,7 +1408,14 @@ namespace ts.Completions {
|
||||
case SyntaxKind.SetKeyword:
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isClassMemberCompletionKeywordText(text: string) {
|
||||
return isClassMemberCompletionKeyword(stringToToken(text));
|
||||
}
|
||||
|
||||
const classMemberKeywordCompletions = filter(keywordCompletions, entry =>
|
||||
isClassMemberCompletionKeywordText(entry.name));
|
||||
|
||||
function isEqualityExpression(node: Node): node is BinaryExpression {
|
||||
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
|
||||
|
||||
@@ -200,27 +200,33 @@ namespace ts.SymbolDisplay {
|
||||
(location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration
|
||||
// get the signature from the declaration and write it
|
||||
const functionDeclaration = <FunctionLikeDeclaration>location.parent;
|
||||
const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
|
||||
if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
|
||||
signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
|
||||
}
|
||||
else {
|
||||
signature = allSignatures[0];
|
||||
}
|
||||
// Use function declaration to write the signatures only if the symbol corresponding to this declaration
|
||||
const locationIsSymbolDeclaration = findDeclaration(symbol, declaration =>
|
||||
declaration === (location.kind === SyntaxKind.ConstructorKeyword ? functionDeclaration.parent : functionDeclaration));
|
||||
|
||||
if (functionDeclaration.kind === SyntaxKind.Constructor) {
|
||||
// show (constructor) Type(...) signature
|
||||
symbolKind = ScriptElementKind.constructorImplementationElement;
|
||||
addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
|
||||
}
|
||||
else {
|
||||
// (function/method) symbol(..signature)
|
||||
addPrefixForAnyFunctionOrVar(functionDeclaration.kind === SyntaxKind.CallSignature &&
|
||||
!(type.symbol.flags & SymbolFlags.TypeLiteral || type.symbol.flags & SymbolFlags.ObjectLiteral) ? type.symbol : symbol, symbolKind);
|
||||
}
|
||||
if (locationIsSymbolDeclaration) {
|
||||
const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
|
||||
if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
|
||||
signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
|
||||
}
|
||||
else {
|
||||
signature = allSignatures[0];
|
||||
}
|
||||
|
||||
addSignatureDisplayParts(signature, allSignatures);
|
||||
hasAddedSymbolInfo = true;
|
||||
if (functionDeclaration.kind === SyntaxKind.Constructor) {
|
||||
// show (constructor) Type(...) signature
|
||||
symbolKind = ScriptElementKind.constructorImplementationElement;
|
||||
addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
|
||||
}
|
||||
else {
|
||||
// (function/method) symbol(..signature)
|
||||
addPrefixForAnyFunctionOrVar(functionDeclaration.kind === SyntaxKind.CallSignature &&
|
||||
!(type.symbol.flags & SymbolFlags.TypeLiteral || type.symbol.flags & SymbolFlags.ObjectLiteral) ? type.symbol : symbol, symbolKind);
|
||||
}
|
||||
|
||||
addSignatureDisplayParts(signature, allSignatures);
|
||||
hasAddedSymbolInfo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user