@@ -649,6 +649,7 @@ func isDeclarationStatementKind(kind Kind) bool {
649
649
KindImportEqualsDeclaration ,
650
650
KindExportDeclaration ,
651
651
KindExportAssignment ,
652
+ KindJSExportAssignment ,
652
653
KindNamespaceExportDeclaration :
653
654
return true
654
655
}
@@ -1304,7 +1305,7 @@ func GetElementOrPropertyAccessArgumentExpressionOrName(node *Node) *Node {
1304
1305
}
1305
1306
1306
1307
func GetElementOrPropertyAccessName (node * Node ) string {
1307
- name := getElementOrPropertyAccessArgumentExpressionOrName (node )
1308
+ name := GetElementOrPropertyAccessArgumentExpressionOrName (node )
1308
1309
if name == nil {
1309
1310
return ""
1310
1311
}
@@ -1351,10 +1352,10 @@ func GetNonAssignedNameOfDeclaration(declaration *Node) *Node {
1351
1352
switch declaration .Kind {
1352
1353
case KindBinaryExpression :
1353
1354
if IsFunctionPropertyAssignment (declaration ) {
1354
- return getElementOrPropertyAccessArgumentExpressionOrName (declaration .AsBinaryExpression ().Left )
1355
+ return GetElementOrPropertyAccessArgumentExpressionOrName (declaration .AsBinaryExpression ().Left )
1355
1356
}
1356
1357
return nil
1357
- case KindExportAssignment :
1358
+ case KindExportAssignment , KindJSExportAssignment :
1358
1359
expr := declaration .AsExportAssignment ().Expression
1359
1360
if IsIdentifier (expr ) {
1360
1361
return expr
@@ -1414,22 +1415,6 @@ func IsFunctionPropertyAssignment(node *Node) bool {
1414
1415
return false
1415
1416
}
1416
1417
1417
- // Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions
1418
- // throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand)
1419
- func getElementOrPropertyAccessArgumentExpressionOrName (node * Node ) * Node {
1420
- switch node .Kind {
1421
- case KindPropertyAccessExpression :
1422
- return node .Name ()
1423
- case KindElementAccessExpression :
1424
- arg := SkipParentheses (node .AsElementAccessExpression ().ArgumentExpression )
1425
- if IsStringOrNumericLiteralLike (arg ) {
1426
- return arg
1427
- }
1428
- return node
1429
- }
1430
- panic ("Unhandled case in getElementOrPropertyAccessArgumentExpressionOrName" )
1431
- }
1432
-
1433
1418
/**
1434
1419
* A declaration has a dynamic name if all of the following are true:
1435
1420
* 1. The declaration has a computed property name.
@@ -1495,10 +1480,6 @@ func IsEffectiveExternalModule(node *SourceFile, compilerOptions *core.CompilerO
1495
1480
return IsExternalModule (node ) || (isCommonJSContainingModuleKind (compilerOptions .GetEmitModuleKind ()) && node .CommonJSModuleIndicator != nil )
1496
1481
}
1497
1482
1498
- func IsEffectiveExternalModuleWorker (node * SourceFile , moduleKind core.ModuleKind ) bool {
1499
- return IsExternalModule (node ) || (isCommonJSContainingModuleKind (moduleKind ) && node .CommonJSModuleIndicator != nil )
1500
- }
1501
-
1502
1483
func isCommonJSContainingModuleKind (kind core.ModuleKind ) bool {
1503
1484
return kind == core .ModuleKindCommonJS || kind == core .ModuleKindNode16 || kind == core .ModuleKindNodeNext
1504
1485
}
@@ -1668,20 +1649,7 @@ func IsEnumConst(node *Node) bool {
1668
1649
}
1669
1650
1670
1651
func ExportAssignmentIsAlias (node * Node ) bool {
1671
- return isAliasableExpression (getExportAssignmentExpression (node ))
1672
- }
1673
-
1674
- func getExportAssignmentExpression (node * Node ) * Node {
1675
- switch node .Kind {
1676
- case KindExportAssignment :
1677
- return node .AsExportAssignment ().Expression
1678
- case KindBinaryExpression :
1679
- return node .AsBinaryExpression ().Right
1680
- }
1681
- panic ("Unhandled case in getExportAssignmentExpression" )
1682
- }
1683
-
1684
- func isAliasableExpression (e * Node ) bool {
1652
+ e := node .AsExportAssignment ().Expression
1685
1653
return IsEntityNameExpression (e ) || IsClassExpression (e )
1686
1654
}
1687
1655
@@ -2086,6 +2054,7 @@ func GetMeaningFromDeclaration(node *Node) SemanticMeaning {
2086
2054
KindImportEqualsDeclaration ,
2087
2055
KindImportDeclaration ,
2088
2056
KindExportAssignment ,
2057
+ KindJSExportAssignment ,
2089
2058
KindExportDeclaration :
2090
2059
return SemanticMeaningAll
2091
2060
@@ -2474,22 +2443,27 @@ func IsNonLocalAlias(symbol *Symbol, excludes SymbolFlags) bool {
2474
2443
// An alias symbol is created by one of the following declarations:
2475
2444
//
2476
2445
// import <symbol> = ...
2446
+ // const <symbol> = ... (JS only)
2447
+ // const { <symbol>, ... } = ... (JS only)
2477
2448
// import <symbol> from ...
2478
2449
// import * as <symbol> from ...
2479
2450
// import { x as <symbol> } from ...
2480
2451
// export { x as <symbol> } from ...
2481
2452
// export * as ns <symbol> from ...
2482
2453
// export = <EntityNameExpression>
2483
2454
// export default <EntityNameExpression>
2455
+ // module.exports = <EntityNameExpression> (JS only)
2484
2456
func IsAliasSymbolDeclaration (node * Node ) bool {
2485
2457
switch node .Kind {
2486
2458
case KindImportEqualsDeclaration , KindNamespaceExportDeclaration , KindNamespaceImport , KindNamespaceExport ,
2487
2459
KindImportSpecifier , KindExportSpecifier :
2488
2460
return true
2489
2461
case KindImportClause :
2490
2462
return node .AsImportClause ().Name () != nil
2491
- case KindExportAssignment :
2463
+ case KindExportAssignment , KindJSExportAssignment :
2492
2464
return ExportAssignmentIsAlias (node )
2465
+ case KindVariableDeclaration , KindBindingElement :
2466
+ return IsVariableDeclarationInitializedToRequire (node )
2493
2467
}
2494
2468
return false
2495
2469
}
@@ -2568,7 +2542,7 @@ func ForEachDynamicImportOrRequireCall(
2568
2542
lastIndex , size := findImportOrRequire (file .Text (), 0 )
2569
2543
for lastIndex >= 0 {
2570
2544
node := GetNodeAtPosition (file , lastIndex , isJavaScriptFile && includeTypeSpaceImports )
2571
- if isJavaScriptFile && IsRequireCall (node , requireStringLiteralLikeArgument ) {
2545
+ if isJavaScriptFile && IsRequireCall (node ) {
2572
2546
if cb (node , node .Arguments ()[0 ]) {
2573
2547
return true
2574
2548
}
@@ -2595,7 +2569,8 @@ func ForEachDynamicImportOrRequireCall(
2595
2569
return false
2596
2570
}
2597
2571
2598
- func IsRequireCall (node * Node , requireStringLiteralLikeArgument bool ) bool {
2572
+ // IsVariableDeclarationInitializedToRequire should be used wherever parent pointers are set
2573
+ func IsRequireCall (node * Node ) bool {
2599
2574
if ! IsCallExpression (node ) {
2600
2575
return false
2601
2576
}
@@ -2606,7 +2581,7 @@ func IsRequireCall(node *Node, requireStringLiteralLikeArgument bool) bool {
2606
2581
if len (call .Arguments .Nodes ) != 1 {
2607
2582
return false
2608
2583
}
2609
- return ! requireStringLiteralLikeArgument || IsStringLiteralLike (call .Arguments .Nodes [0 ])
2584
+ return IsStringLiteralLike (call .Arguments .Nodes [0 ])
2610
2585
}
2611
2586
2612
2587
func IsUnterminatedLiteral (node * Node ) bool {
@@ -2664,6 +2639,36 @@ func GetPragmaArgument(pragma *Pragma, name string) string {
2664
2639
return ""
2665
2640
}
2666
2641
2642
+ // Of the form: `const x = require("x")` or `const { x } = require("x")` or with `var` or `let`
2643
+ // The variable must not be exported and must not have a type annotation, even a jsdoc one.
2644
+ // The initializer must be a call to `require` with a string literal or a string literal-like argument.
2645
+ func IsVariableDeclarationInitializedToRequire (node * Node ) bool {
2646
+ if ! IsInJSFile (node ) {
2647
+ return false
2648
+ }
2649
+ if node .Kind == KindBindingElement {
2650
+ node = node .Parent .Parent
2651
+ }
2652
+ if node .Kind != KindVariableDeclaration {
2653
+ return false
2654
+ }
2655
+
2656
+ return node .Parent .Parent .ModifierFlags ()& ModifierFlagsExport == 0 &&
2657
+ node .AsVariableDeclaration ().Initializer != nil &&
2658
+ node .Type () == nil &&
2659
+ IsRequireCall (node .AsVariableDeclaration ().Initializer )
2660
+ }
2661
+
2662
+ func IsModuleExportsAccessExpression (node * Node ) bool {
2663
+ return (IsPropertyAccessExpression (node ) || isLiteralLikeElementAccess (node )) &&
2664
+ IsModuleIdentifier (node .Expression ()) &&
2665
+ GetElementOrPropertyAccessName (node ) == "exports"
2666
+ }
2667
+
2668
+ func isLiteralLikeElementAccess (node * Node ) bool {
2669
+ return node .Kind == KindElementAccessExpression && IsStringOrNumericLiteralLike (node .AsElementAccessExpression ().ArgumentExpression )
2670
+ }
2671
+
2667
2672
func IsCheckJSEnabledForFile (sourceFile * SourceFile , compilerOptions * core.CompilerOptions ) bool {
2668
2673
if sourceFile .CheckJsDirective != nil {
2669
2674
return sourceFile .CheckJsDirective .Enabled
0 commit comments