Skip to content

Commit

Permalink
Filter out global keywords of UMD module export declarations in compl…
Browse files Browse the repository at this point in the history
…etion providing auto import suggestions (microsoft#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
  • Loading branch information
aminpaks authored Jan 25, 2021
1 parent 154f209 commit 290af69
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 1 deletion.
18 changes: 17 additions & 1 deletion src/services/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
}
});
Original file line number Diff line number Diff line change
@@ -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,
}
});
32 changes: 32 additions & 0 deletions tests/cases/fourslash/completionsImport_umdModules3_script.ts
Original file line number Diff line number Diff line change
@@ -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,
}
});

0 comments on commit 290af69

Please sign in to comment.