mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Merge pull request #30414 from Microsoft/jsSyntaxCompletions
Filter ts only keywords from js file completion
This commit is contained in:
@@ -4552,9 +4552,47 @@ namespace FourSlashInterface {
|
||||
];
|
||||
}
|
||||
|
||||
function getInJsKeywords(keywords: ReadonlyArray<ExpectedCompletionEntryObject>): ReadonlyArray<ExpectedCompletionEntryObject> {
|
||||
return keywords.filter(keyword => {
|
||||
switch (keyword.name) {
|
||||
case "enum":
|
||||
case "interface":
|
||||
case "implements":
|
||||
case "private":
|
||||
case "protected":
|
||||
case "public":
|
||||
case "abstract":
|
||||
case "any":
|
||||
case "boolean":
|
||||
case "declare":
|
||||
case "infer":
|
||||
case "is":
|
||||
case "keyof":
|
||||
case "module":
|
||||
case "namespace":
|
||||
case "never":
|
||||
case "readonly":
|
||||
case "number":
|
||||
case "object":
|
||||
case "string":
|
||||
case "symbol":
|
||||
case "type":
|
||||
case "unique":
|
||||
case "unknown":
|
||||
case "global":
|
||||
case "bigint":
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const classElementKeywords: ReadonlyArray<ExpectedCompletionEntryObject> =
|
||||
["private", "protected", "public", "static", "abstract", "async", "constructor", "get", "readonly", "set"].map(keywordEntry);
|
||||
|
||||
export const classElementInJsKeywords = getInJsKeywords(classElementKeywords);
|
||||
|
||||
export const constructorParameterKeywords: ReadonlyArray<ExpectedCompletionEntryObject> =
|
||||
["private", "protected", "public", "readonly"].map((name): ExpectedCompletionEntryObject => ({ name, kind: "keyword" }));
|
||||
|
||||
@@ -4692,6 +4730,8 @@ namespace FourSlashInterface {
|
||||
}
|
||||
});
|
||||
|
||||
export const statementInJsKeywords = getInJsKeywords(statementKeywords);
|
||||
|
||||
export const globalsVars: ReadonlyArray<ExpectedCompletionEntryObject> = [
|
||||
functionEntry("eval"),
|
||||
functionEntry("parseInt"),
|
||||
@@ -4793,6 +4833,18 @@ namespace FourSlashInterface {
|
||||
...globalKeywordsInsideFunction,
|
||||
];
|
||||
|
||||
const globalInJsKeywordsInsideFunction = getInJsKeywords(globalKeywordsInsideFunction);
|
||||
|
||||
// TODO: many of these are inappropriate to always provide
|
||||
export const globalsInJsInsideFunction = (plus: ReadonlyArray<ExpectedCompletionEntry>): ReadonlyArray<ExpectedCompletionEntry> => [
|
||||
{ name: "arguments", kind: "local var" },
|
||||
{ name: "globalThis", kind: "module" },
|
||||
...globalsVars,
|
||||
...plus,
|
||||
{ name: "undefined", kind: "var" },
|
||||
...globalInJsKeywordsInsideFunction,
|
||||
];
|
||||
|
||||
// TODO: many of these are inappropriate to always provide
|
||||
export const globalKeywords: ReadonlyArray<ExpectedCompletionEntryObject> = [
|
||||
"break",
|
||||
@@ -4871,6 +4923,8 @@ namespace FourSlashInterface {
|
||||
"of",
|
||||
].map(keywordEntry);
|
||||
|
||||
export const globalInJsKeywords = getInJsKeywords(globalKeywords);
|
||||
|
||||
export const insideMethodKeywords: ReadonlyArray<ExpectedCompletionEntryObject> = [
|
||||
"break",
|
||||
"case",
|
||||
@@ -4917,6 +4971,8 @@ namespace FourSlashInterface {
|
||||
"await",
|
||||
].map(keywordEntry);
|
||||
|
||||
export const insideMethodInJsKeywords = getInJsKeywords(insideMethodKeywords);
|
||||
|
||||
export const globalKeywordsPlusUndefined: ReadonlyArray<ExpectedCompletionEntryObject> = (() => {
|
||||
const i = ts.findIndex(globalKeywords, x => x.name === "unique");
|
||||
return [...globalKeywords.slice(0, i), keywordEntry("undefined"), ...globalKeywords.slice(i)];
|
||||
@@ -4929,6 +4985,13 @@ namespace FourSlashInterface {
|
||||
...globalKeywords
|
||||
];
|
||||
|
||||
export const globalsInJs: ReadonlyArray<ExpectedCompletionEntryObject> = [
|
||||
{ name: "globalThis", kind: "module" },
|
||||
...globalsVars,
|
||||
{ name: "undefined", kind: "var" },
|
||||
...globalInJsKeywords
|
||||
];
|
||||
|
||||
export function globalsPlus(plus: ReadonlyArray<ExpectedCompletionEntry>): ReadonlyArray<ExpectedCompletionEntry> {
|
||||
return [
|
||||
{ name: "globalThis", kind: "module" },
|
||||
@@ -4937,6 +5000,15 @@ namespace FourSlashInterface {
|
||||
{ name: "undefined", kind: "var" },
|
||||
...globalKeywords];
|
||||
}
|
||||
|
||||
export function globalsInJsPlus(plus: ReadonlyArray<ExpectedCompletionEntry>): ReadonlyArray<ExpectedCompletionEntry> {
|
||||
return [
|
||||
{ name: "globalThis", kind: "module" },
|
||||
...globalsVars,
|
||||
...plus,
|
||||
{ name: "undefined", kind: "var" },
|
||||
...globalInJsKeywords];
|
||||
}
|
||||
}
|
||||
|
||||
export interface ReferenceGroup {
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace ts.Completions {
|
||||
ConstructorParameterKeywords, // Keywords at constructor parameter
|
||||
FunctionLikeBodyKeywords, // Keywords at function like body
|
||||
TypeKeywords,
|
||||
Last = TypeKeywords
|
||||
}
|
||||
|
||||
const enum GlobalsSearch { Continue, Success, Fail }
|
||||
@@ -77,7 +78,7 @@ 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;
|
||||
const { symbols, completionKind, isInSnippetScope, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, literals, symbolToOriginInfoMap, recommendedCompletion, isJsxInitializer, insideJsDocTagTypeExpression } = completionData;
|
||||
|
||||
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,
|
||||
@@ -113,7 +114,7 @@ namespace ts.Completions {
|
||||
|
||||
if (keywordFilters !== KeywordCompletionFilters.None) {
|
||||
const entryNames = arrayToSet(entries, e => e.name);
|
||||
for (const keywordEntry of getKeywordCompletions(keywordFilters)) {
|
||||
for (const keywordEntry of getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && isSourceFileJS(sourceFile))) {
|
||||
if (!entryNames.has(keywordEntry.name)) {
|
||||
entries.push(keywordEntry);
|
||||
}
|
||||
@@ -510,6 +511,7 @@ namespace ts.Completions {
|
||||
readonly recommendedCompletion: Symbol | undefined;
|
||||
readonly previousToken: Node | undefined;
|
||||
readonly isJsxInitializer: IsJsxInitializer;
|
||||
readonly insideJsDocTagTypeExpression: boolean;
|
||||
}
|
||||
type Request = { readonly kind: CompletionDataKind.JsDocTagName | CompletionDataKind.JsDocTag } | { readonly kind: CompletionDataKind.JsDocParameterName, tag: JSDocParameterTag };
|
||||
|
||||
@@ -837,7 +839,22 @@ namespace ts.Completions {
|
||||
const literals = mapDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), t => t.isLiteral() ? t.value : undefined);
|
||||
|
||||
const recommendedCompletion = previousToken && contextualType && getRecommendedCompletion(previousToken, contextualType, typeChecker);
|
||||
return { kind: CompletionDataKind.Data, symbols, completionKind, isInSnippetScope, propertyAccessToConvert, isNewIdentifierLocation, location, keywordFilters, literals, symbolToOriginInfoMap, recommendedCompletion, previousToken, isJsxInitializer };
|
||||
return {
|
||||
kind: CompletionDataKind.Data,
|
||||
symbols,
|
||||
completionKind,
|
||||
isInSnippetScope,
|
||||
propertyAccessToConvert,
|
||||
isNewIdentifierLocation,
|
||||
location,
|
||||
keywordFilters,
|
||||
literals,
|
||||
symbolToOriginInfoMap,
|
||||
recommendedCompletion,
|
||||
previousToken,
|
||||
isJsxInitializer,
|
||||
insideJsDocTagTypeExpression
|
||||
};
|
||||
|
||||
type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag;
|
||||
|
||||
@@ -1929,7 +1946,18 @@ namespace ts.Completions {
|
||||
}
|
||||
return res;
|
||||
});
|
||||
function getKeywordCompletions(keywordFilter: KeywordCompletionFilters): ReadonlyArray<CompletionEntry> {
|
||||
|
||||
function getKeywordCompletions(keywordFilter: KeywordCompletionFilters, filterOutTsOnlyKeywords: boolean): ReadonlyArray<CompletionEntry> {
|
||||
if (!filterOutTsOnlyKeywords) return getTypescriptKeywordCompletions(keywordFilter);
|
||||
|
||||
const index = keywordFilter + KeywordCompletionFilters.Last + 1;
|
||||
return _keywordCompletions[index] ||
|
||||
(_keywordCompletions[index] = getTypescriptKeywordCompletions(keywordFilter)
|
||||
.filter(entry => !isTypeScriptOnlyKeyword(stringToToken(entry.name)!))
|
||||
);
|
||||
}
|
||||
|
||||
function getTypescriptKeywordCompletions(keywordFilter: KeywordCompletionFilters): ReadonlyArray<CompletionEntry> {
|
||||
return _keywordCompletions[keywordFilter] || (_keywordCompletions[keywordFilter] = allKeywordsCompletions().filter(entry => {
|
||||
const kind = stringToToken(entry.name)!;
|
||||
switch (keywordFilter) {
|
||||
@@ -1954,6 +1982,40 @@ namespace ts.Completions {
|
||||
}));
|
||||
}
|
||||
|
||||
function isTypeScriptOnlyKeyword(kind: SyntaxKind) {
|
||||
switch (kind) {
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
case SyntaxKind.GlobalKeyword:
|
||||
case SyntaxKind.ImplementsKeyword:
|
||||
case SyntaxKind.InferKeyword:
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.IsKeyword:
|
||||
case SyntaxKind.KeyOfKeyword:
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
case SyntaxKind.NamespaceKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
case SyntaxKind.UniqueKeyword:
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isInterfaceOrTypeLiteralCompletionKeyword(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.ReadonlyKeyword;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user