Skip to content

Commit 7e3af08

Browse files
author
Andy
authored
Don't add a suggestion to convert to an es6 module if no commonjs import/export appears at top-level. (#24101)
1 parent 9b6378b commit 7e3af08

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/services/suggestionDiagnostics.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ namespace ts {
55
const checker = program.getDiagnosticsProducingTypeChecker();
66
const diags: Diagnostic[] = [];
77

8-
if (sourceFile.commonJsModuleIndicator && (programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions()))) {
8+
if (sourceFile.commonJsModuleIndicator &&
9+
(programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) &&
10+
containsTopLevelCommonjs(sourceFile)) {
911
diags.push(createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module));
1012
}
1113

@@ -61,6 +63,29 @@ namespace ts {
6163
return diags.concat(checker.getSuggestionDiagnostics(sourceFile));
6264
}
6365

66+
// convertToEs6Module only works on top-level, so don't trigger it if commonjs code only appears in nested scopes.
67+
function containsTopLevelCommonjs(sourceFile: SourceFile): boolean {
68+
return sourceFile.statements.some(statement => {
69+
switch (statement.kind) {
70+
case SyntaxKind.VariableStatement:
71+
return (statement as VariableStatement).declarationList.declarations.some(decl =>
72+
isRequireCall(propertyAccessLeftHandSide(decl.initializer), /*checkArgumentIsStringLiteralLike*/ true));
73+
case SyntaxKind.ExpressionStatement: {
74+
const { expression } = statement as ExpressionStatement;
75+
if (!isBinaryExpression(expression)) return isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true);
76+
const kind = getSpecialPropertyAssignmentKind(expression);
77+
return kind === SpecialPropertyAssignmentKind.ExportsProperty || kind === SpecialPropertyAssignmentKind.ModuleExports;
78+
}
79+
default:
80+
return false;
81+
}
82+
});
83+
}
84+
85+
function propertyAccessLeftHandSide(node: Expression): Expression {
86+
return isPropertyAccessExpression(node) ? propertyAccessLeftHandSide(node.expression) : node;
87+
}
88+
6489
function importNameForConvertToDefaultImport(node: AnyValidImportOrReExport): Identifier | undefined {
6590
switch (node.kind) {
6691
case SyntaxKind.ImportDeclaration:
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @allowJs: true
4+
// @target: esnext
5+
6+
// @Filename: /a.js
7+
////(function() {
8+
//// module.exports = 0;
9+
////})();
10+
11+
verify.getSuggestionDiagnostics([]);
12+

0 commit comments

Comments
 (0)