Filter out global keywords of UMD module export declarations in completion providing auto import suggestions (#42141)

* Add AutoImportSuggestions for UMD module export declarations instead of global keywords

* Add test for scripts

* Add more comments

* Provide auto import suggestion only for modules and not scripts

* PR review #1

* PR review #1
This commit is contained in:
Amin Pakseresht 2021-01-25 12:29:13 -05:00 committed by GitHub
parent 154f2094fc
commit 290af69b73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 1 deletions

View File

@ -855,6 +855,7 @@ namespace ts.Completions {
host: LanguageServiceHost
): CompletionData | Request | undefined {
const typeChecker = program.getTypeChecker();
const compilerOptions = program.getCompilerOptions();
let start = timestamp();
let currentToken = getTokenAtPosition(sourceFile, position); // TODO: GH#15853
@ -1519,7 +1520,22 @@ namespace ts.Completions {
return false;
}
symbol = skipAlias(symbol, typeChecker);
// External modules can have global export declarations that will be
// available as global keywords in all scopes. But if the external module
// already has an explicit export and user only wants to user explicit
// module imports then the global keywords will be filtered out so auto
// import suggestions will win in the completion
const symbolOrigin = skipAlias(symbol, typeChecker);
// We only want to filter out the global keywords
// Auto Imports are not available for scripts so this conditional is always false
if (!!sourceFile.externalModuleIndicator
&& !compilerOptions.allowUmdGlobalAccess
&& symbolToSortTextMap[getSymbolId(symbol)] === SortText.GlobalsOrKeywords
&& symbolToSortTextMap[getSymbolId(symbolOrigin)] === SortText.AutoImportSuggestions) {
return false;
}
// Continue with origin symbol
symbol = symbolOrigin;
// import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
if (isInRightSideOfInternalImportEqualsDeclaration(location)) {

View File

@ -0,0 +1,33 @@
/// <reference path="./fourslash.ts" />
// @filename: /package.json
//// { "dependencies": { "@types/classnames": "*" } }
// @filename: /tsconfig.json
//// { "compilerOptions": { "allowUmdGlobalAccess": true } }
// @filename: /node_modules/@types/classnames/package.json
//// { "name": "@types/classnames", "types": "index.d.ts" }
// @filename: /node_modules/@types/classnames/index.d.ts
//// declare const classNames: () => string;
//// export = classNames;
//// export as namespace classNames;
// @filename: /SomeReactComponent.tsx
//// import * as React from 'react';
////
//// const el1 = <div className={class/*1*/}>foo</div>;
goTo.marker("1");
verify.completions({
includes: [{
name: "classNames",
hasAction: undefined, // Asserts to have no actions
sortText: completion.SortText.GlobalsOrKeywords,
}],
preferences: {
includeCompletionsForModuleExports: true,
}
});

View File

@ -0,0 +1,34 @@
/// <reference path="./fourslash.ts" />
// @filename: /package.json
//// { "dependencies": { "@types/classnames": "*" } }
// @filename: /tsconfig.json
//// {}
// @filename: /node_modules/@types/classnames/package.json
//// { "name": "@types/classnames", "types": "index.d.ts" }
// @filename: /node_modules/@types/classnames/index.d.ts
//// declare const classNames: () => string;
//// export = classNames;
//// export as namespace classNames;
// @filename: /SomeReactComponent.tsx
//// import * as React from 'react';
////
//// const el1 = <div className={class/*1*/}>foo</div>;
goTo.marker("1");
verify.completions({
includes: [{
name: "classNames",
hasAction: true,
source: "/node_modules/@types/classnames/index",
sortText: completion.SortText.AutoImportSuggestions,
}],
preferences: {
includeCompletionsForModuleExports: true,
}
});

View File

@ -0,0 +1,32 @@
/// <reference path="./fourslash.ts" />
// @filename: /package.json
//// { "dependencies": { "@types/classnames": "*" } }
// @filename: /tsconfig.json
//// { "compilerOptions": { "module": "es2015" }}
// @filename: /node_modules/@types/classnames/package.json
//// { "name": "@types/classnames", "types": "index.d.ts" }
// @filename: /node_modules/@types/classnames/index.d.ts
//// declare const classNames: () => string;
//// export = classNames;
//// export as namespace classNames;
// @filename: /SomeReactComponent.tsx
////
//// const el1 = <div className={class/*1*/}>foo</div>
goTo.marker("1");
verify.completions({
includes: [{
name: "classNames",
hasAction: undefined, // Asserts to have no actions
sortText: completion.SortText.GlobalsOrKeywords,
}],
preferences: {
includeCompletionsForModuleExports: true,
}
});