@effect/language-service 0.22.3 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/index.js +230 -104
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +2 -1
- package/transform.js.map +1 -1
package/README.md
CHANGED
|
@@ -84,8 +84,10 @@ Few options can be provided alongside the initialization of the Language Service
|
|
|
84
84
|
},
|
|
85
85
|
"quickinfo": true, // controls quickinfo over Effect (default: true)
|
|
86
86
|
"completions": true, // controls Effect completions (default: true)
|
|
87
|
+
"goto": true, // controls Effect goto references (default: true)
|
|
87
88
|
"allowedDuplicatedPackages": [], // list of package names that has effect in peer dependencies and are allowed to be duplicated (default: [])
|
|
88
|
-
"
|
|
89
|
+
"barrelImportPackages": [], // package names that should be preferred as imported from the top level barrel file (default: [])
|
|
90
|
+
"namespaceImportPackages": [] // package names that should be preferred as imported with namespace imports e.g. ["effect"] (default: [])
|
|
89
91
|
}
|
|
90
92
|
]
|
|
91
93
|
}
|
package/index.js
CHANGED
|
@@ -1423,7 +1423,8 @@ function parse(config) {
|
|
|
1423
1423
|
completions: isObject(config) && hasProperty(config, "completions") && isBoolean(config.completions) ? config.completions : true,
|
|
1424
1424
|
goto: isObject(config) && hasProperty(config, "goto") && isBoolean(config.goto) ? config.goto : true,
|
|
1425
1425
|
allowedDuplicatedPackages: isObject(config) && hasProperty(config, "allowedDuplicatedPackages") && isArray(config.allowedDuplicatedPackages) && config.allowedDuplicatedPackages.every(isString) ? config.allowedDuplicatedPackages.map((_) => _.toLowerCase()) : [],
|
|
1426
|
-
namespaceImportPackages: isObject(config) && hasProperty(config, "namespaceImportPackages") && isArray(config.namespaceImportPackages) && config.namespaceImportPackages.every(isString) ? config.namespaceImportPackages.map((_) => _.toLowerCase()) : []
|
|
1426
|
+
namespaceImportPackages: isObject(config) && hasProperty(config, "namespaceImportPackages") && isArray(config.namespaceImportPackages) && config.namespaceImportPackages.every(isString) ? config.namespaceImportPackages.map((_) => _.toLowerCase()) : [],
|
|
1427
|
+
barrelImportPackages: isObject(config) && hasProperty(config, "barrelImportPackages") && isArray(config.barrelImportPackages) && config.barrelImportPackages.every(isString) ? config.barrelImportPackages.map((_) => _.toLowerCase()) : []
|
|
1427
1428
|
};
|
|
1428
1429
|
}
|
|
1429
1430
|
|
|
@@ -3484,7 +3485,7 @@ var completions = [
|
|
|
3484
3485
|
effectDiagnosticsComment
|
|
3485
3486
|
];
|
|
3486
3487
|
|
|
3487
|
-
// src/completions/
|
|
3488
|
+
// src/completions/middlewareAutoImports.ts
|
|
3488
3489
|
var importablePackagesMetadataCache = /* @__PURE__ */ new Map();
|
|
3489
3490
|
var makeImportablePackagesMetadata = fn("makeImportablePackagesMetadata")(function* (sourceFile) {
|
|
3490
3491
|
const ts = yield* service(TypeScriptApi);
|
|
@@ -3495,7 +3496,17 @@ var makeImportablePackagesMetadata = fn("makeImportablePackagesMetadata")(functi
|
|
|
3495
3496
|
const excludedByFileName = /* @__PURE__ */ new Map();
|
|
3496
3497
|
const unbarreledModulePathByFileName = /* @__PURE__ */ new Map();
|
|
3497
3498
|
const barreledModulePathByFileName = /* @__PURE__ */ new Map();
|
|
3498
|
-
|
|
3499
|
+
const packages = [
|
|
3500
|
+
...languageServicePluginOptions.namespaceImportPackages.map((packageName) => ({
|
|
3501
|
+
packageName,
|
|
3502
|
+
kind: "namespace"
|
|
3503
|
+
})),
|
|
3504
|
+
...languageServicePluginOptions.barrelImportPackages.map((packageName) => ({
|
|
3505
|
+
packageName,
|
|
3506
|
+
kind: "barrel"
|
|
3507
|
+
}))
|
|
3508
|
+
];
|
|
3509
|
+
for (const { kind, packageName } of packages) {
|
|
3499
3510
|
const barrelModule = ts.resolveModuleName(packageName, sourceFile.fileName, program.getCompilerOptions(), host);
|
|
3500
3511
|
if (barrelModule.resolvedModule) {
|
|
3501
3512
|
const barrelPath = barrelModule.resolvedModule.resolvedFileName;
|
|
@@ -3515,25 +3526,32 @@ var makeImportablePackagesMetadata = fn("makeImportablePackagesMetadata")(functi
|
|
|
3515
3526
|
if (unbarreledModulePathResolved.resolvedModule) {
|
|
3516
3527
|
const unbarreledModulePath = unbarreledModulePathResolved.resolvedModule.resolvedFileName;
|
|
3517
3528
|
if (exportClause && ts.isNamespaceExport(exportClause) && ts.isIdentifier(exportClause.name)) {
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
+
if (kind === "namespace") {
|
|
3530
|
+
namespaceByFileName.set(unbarreledModulePath, exportClause.name.text);
|
|
3531
|
+
const existingUnbarreledModulePath = unbarreledModulePathByFileName.get(barrelSource.fileName) || [];
|
|
3532
|
+
existingUnbarreledModulePath.push({
|
|
3533
|
+
fileName: unbarreledModulePath,
|
|
3534
|
+
exportName: exportClause.name.text
|
|
3535
|
+
});
|
|
3536
|
+
unbarreledModulePathByFileName.set(barrelSource.fileName, existingUnbarreledModulePath);
|
|
3537
|
+
}
|
|
3538
|
+
if (kind === "barrel") {
|
|
3539
|
+
barreledModulePathByFileName.set(unbarreledModulePath, {
|
|
3540
|
+
fileName: barrelSource.fileName,
|
|
3541
|
+
exportName: exportClause.name.text,
|
|
3542
|
+
packageName
|
|
3543
|
+
});
|
|
3544
|
+
}
|
|
3529
3545
|
}
|
|
3530
3546
|
if (exportClause && ts.isNamedExports(exportClause)) {
|
|
3531
3547
|
for (const element of exportClause.elements) {
|
|
3532
3548
|
if (!ts.isIdentifier(element.name)) continue;
|
|
3533
3549
|
const methodName = element.name.text;
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3550
|
+
if (kind === "namespace") {
|
|
3551
|
+
const excludedMethods = excludedByFileName.get(methodName) || [];
|
|
3552
|
+
excludedMethods.push(unbarreledModulePath);
|
|
3553
|
+
excludedByFileName.set(methodName, excludedMethods);
|
|
3554
|
+
}
|
|
3537
3555
|
}
|
|
3538
3556
|
}
|
|
3539
3557
|
}
|
|
@@ -3553,7 +3571,7 @@ var makeImportablePackagesMetadata = fn("makeImportablePackagesMetadata")(functi
|
|
|
3553
3571
|
var appendEffectCompletionEntryData = fn("appendEffectCompletionEntryData")(
|
|
3554
3572
|
function* (_sourceFile, applicableCompletions) {
|
|
3555
3573
|
const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
|
|
3556
|
-
if (languageServicePluginOptions.namespaceImportPackages.length === 0) return applicableCompletions;
|
|
3574
|
+
if (languageServicePluginOptions.namespaceImportPackages.length === 0 && languageServicePluginOptions.barrelImportPackages.length === 0) return applicableCompletions;
|
|
3557
3575
|
if (applicableCompletions) {
|
|
3558
3576
|
return {
|
|
3559
3577
|
...applicableCompletions,
|
|
@@ -3571,41 +3589,157 @@ var appendEffectCompletionEntryData = fn("appendEffectCompletionEntryData")(
|
|
|
3571
3589
|
return applicableCompletions;
|
|
3572
3590
|
}
|
|
3573
3591
|
);
|
|
3574
|
-
var
|
|
3575
|
-
function* (sourceFile,
|
|
3576
|
-
const
|
|
3577
|
-
if (
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3592
|
+
var isAutoImportOnlyCodeActions = fn("isAutoImportOnlyCodeActions")(
|
|
3593
|
+
function* (sourceFile, codeActions, exportName) {
|
|
3594
|
+
const ts = yield* service(TypeScriptApi);
|
|
3595
|
+
if (!codeActions) return;
|
|
3596
|
+
if (codeActions.length !== 1) return;
|
|
3597
|
+
const action = codeActions[0];
|
|
3598
|
+
const changes = action.changes;
|
|
3599
|
+
if (changes.length !== 1) return;
|
|
3600
|
+
const fileTextChanges = action.changes[0];
|
|
3601
|
+
if (fileTextChanges.fileName !== sourceFile.fileName) return;
|
|
3602
|
+
const textChanges = fileTextChanges.textChanges;
|
|
3603
|
+
if (textChanges.length !== 1) return;
|
|
3604
|
+
const change = textChanges[0];
|
|
3605
|
+
if (change.newText.trim().toLowerCase().startsWith("import") && change.newText.indexOf(exportName) > -1) {
|
|
3606
|
+
return {
|
|
3607
|
+
type: "create"
|
|
3608
|
+
};
|
|
3609
|
+
}
|
|
3610
|
+
if (change.newText.indexOf(exportName) > -1) {
|
|
3611
|
+
const ancestorNodes = yield* getAncestorNodesInRange(sourceFile, {
|
|
3612
|
+
pos: change.span.start,
|
|
3613
|
+
end: change.span.start
|
|
3614
|
+
});
|
|
3615
|
+
const importNodes = ancestorNodes.filter((node) => ts.isImportDeclaration(node));
|
|
3616
|
+
if (importNodes.length > 0) {
|
|
3617
|
+
return {
|
|
3618
|
+
type: "update"
|
|
3619
|
+
};
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
);
|
|
3624
|
+
var getImportFromNamespaceCodeActions = fn("getImportFromNamespaceCodeActions")(function* (formatOptions, preferences, languageServiceHost, sourceFile, effectReplaceSpan, effectNamespaceName, effectUnbarreledModulePath, newModuleSpecifier) {
|
|
3625
|
+
const ts = yield* service(TypeScriptApi);
|
|
3626
|
+
const formatContext = ts.formatting.getFormatContext(
|
|
3627
|
+
formatOptions || {},
|
|
3628
|
+
languageServiceHost
|
|
3629
|
+
);
|
|
3630
|
+
const changes = ts.textChanges.ChangeTracker.with(
|
|
3631
|
+
{
|
|
3632
|
+
formatContext,
|
|
3633
|
+
host: languageServiceHost,
|
|
3634
|
+
preferences: preferences || {}
|
|
3635
|
+
},
|
|
3636
|
+
(changeTracker) => {
|
|
3637
|
+
ts.insertImports(
|
|
3638
|
+
changeTracker,
|
|
3639
|
+
sourceFile,
|
|
3640
|
+
ts.factory.createImportDeclaration(
|
|
3641
|
+
void 0,
|
|
3642
|
+
ts.factory.createImportClause(
|
|
3643
|
+
false,
|
|
3644
|
+
void 0,
|
|
3645
|
+
ts.factory.createNamespaceImport(ts.factory.createIdentifier(effectNamespaceName))
|
|
3646
|
+
),
|
|
3647
|
+
ts.factory.createStringLiteral(newModuleSpecifier)
|
|
3648
|
+
),
|
|
3649
|
+
true,
|
|
3650
|
+
preferences || {}
|
|
3651
|
+
);
|
|
3652
|
+
if (!effectUnbarreledModulePath) {
|
|
3653
|
+
changeTracker.insertText(
|
|
3654
|
+
sourceFile,
|
|
3655
|
+
effectReplaceSpan.start,
|
|
3656
|
+
effectNamespaceName + "."
|
|
3657
|
+
);
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
);
|
|
3661
|
+
return [
|
|
3662
|
+
{
|
|
3663
|
+
description: "Import * as " + effectNamespaceName + " from " + newModuleSpecifier,
|
|
3664
|
+
changes
|
|
3665
|
+
}
|
|
3666
|
+
];
|
|
3667
|
+
});
|
|
3668
|
+
var getImportFromBarrelCodeActions = fn("getImportFromBarrelCodeActions")(function* (formatOptions, preferences, languageServiceHost, sourceFile, effectReplaceSpan, newModuleSpecifier, barrelExportName) {
|
|
3669
|
+
const ts = yield* service(TypeScriptApi);
|
|
3670
|
+
const formatContext = ts.formatting.getFormatContext(
|
|
3671
|
+
formatOptions || {},
|
|
3672
|
+
languageServiceHost
|
|
3673
|
+
);
|
|
3674
|
+
const changes = ts.textChanges.ChangeTracker.with(
|
|
3675
|
+
{
|
|
3676
|
+
formatContext,
|
|
3677
|
+
host: languageServiceHost,
|
|
3678
|
+
preferences: preferences || {}
|
|
3679
|
+
},
|
|
3680
|
+
(changeTracker) => {
|
|
3681
|
+
let foundImportDeclaration = false;
|
|
3682
|
+
for (const statement of sourceFile.statements) {
|
|
3683
|
+
if (ts.isImportDeclaration(statement)) {
|
|
3684
|
+
const moduleSpecifier = statement.moduleSpecifier;
|
|
3685
|
+
if (moduleSpecifier && ts.isStringLiteral(moduleSpecifier) && moduleSpecifier.text === newModuleSpecifier) {
|
|
3686
|
+
const importClause = statement.importClause;
|
|
3687
|
+
if (importClause && importClause.namedBindings && ts.isNamedImports(importClause.namedBindings)) {
|
|
3688
|
+
const namedImports = importClause.namedBindings;
|
|
3689
|
+
changeTracker.replaceNode(
|
|
3690
|
+
sourceFile,
|
|
3691
|
+
namedImports,
|
|
3692
|
+
ts.factory.createNamedImports(
|
|
3693
|
+
namedImports.elements.concat([
|
|
3694
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier(barrelExportName))
|
|
3695
|
+
])
|
|
3696
|
+
)
|
|
3697
|
+
);
|
|
3698
|
+
foundImportDeclaration = true;
|
|
3699
|
+
break;
|
|
3700
|
+
}
|
|
3605
3701
|
}
|
|
3606
3702
|
}
|
|
3607
3703
|
}
|
|
3608
|
-
|
|
3704
|
+
if (!foundImportDeclaration) {
|
|
3705
|
+
ts.insertImports(
|
|
3706
|
+
changeTracker,
|
|
3707
|
+
sourceFile,
|
|
3708
|
+
ts.factory.createImportDeclaration(
|
|
3709
|
+
void 0,
|
|
3710
|
+
ts.factory.createImportClause(
|
|
3711
|
+
false,
|
|
3712
|
+
void 0,
|
|
3713
|
+
ts.factory.createNamedImports(
|
|
3714
|
+
[
|
|
3715
|
+
ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier(barrelExportName))
|
|
3716
|
+
]
|
|
3717
|
+
)
|
|
3718
|
+
),
|
|
3719
|
+
ts.factory.createStringLiteral(newModuleSpecifier)
|
|
3720
|
+
),
|
|
3721
|
+
true,
|
|
3722
|
+
preferences || {}
|
|
3723
|
+
);
|
|
3724
|
+
}
|
|
3725
|
+
changeTracker.insertText(
|
|
3726
|
+
sourceFile,
|
|
3727
|
+
effectReplaceSpan.start,
|
|
3728
|
+
barrelExportName + "."
|
|
3729
|
+
);
|
|
3730
|
+
}
|
|
3731
|
+
);
|
|
3732
|
+
return [
|
|
3733
|
+
{
|
|
3734
|
+
description: "Import { " + barrelExportName + " } from " + newModuleSpecifier,
|
|
3735
|
+
changes
|
|
3736
|
+
}
|
|
3737
|
+
];
|
|
3738
|
+
});
|
|
3739
|
+
var postprocessCompletionEntryDetails = fn("postprocessCompletionEntryDetails")(
|
|
3740
|
+
function* (sourceFile, data, applicableCompletionEntryDetails, formatOptions, preferences, languageServiceHost) {
|
|
3741
|
+
const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
|
|
3742
|
+
if (languageServicePluginOptions.namespaceImportPackages.length === 0 && languageServicePluginOptions.barrelImportPackages.length === 0) return applicableCompletionEntryDetails;
|
|
3609
3743
|
const ts = yield* service(TypeScriptApi);
|
|
3610
3744
|
const program = yield* service(TypeScriptProgram);
|
|
3611
3745
|
const getModuleSpecifier = makeGetModuleSpecifier(ts);
|
|
@@ -3618,74 +3752,66 @@ var postprocessCompletionEntryDetails = fn("postprocessCompletionEntryDetails")(
|
|
|
3618
3752
|
if (!moduleSpecifier) return applicableCompletionEntryDetails;
|
|
3619
3753
|
if (!("effectReplaceSpan" in data)) return applicableCompletionEntryDetails;
|
|
3620
3754
|
const effectReplaceSpan = data.effectReplaceSpan;
|
|
3621
|
-
const result = yield* isAutoImportOnlyCodeActions(
|
|
3755
|
+
const result = yield* isAutoImportOnlyCodeActions(
|
|
3756
|
+
sourceFile,
|
|
3757
|
+
applicableCompletionEntryDetails.codeActions,
|
|
3758
|
+
exportName
|
|
3759
|
+
);
|
|
3622
3760
|
if (!result) return applicableCompletionEntryDetails;
|
|
3623
3761
|
const packagesMetadata = importablePackagesMetadataCache.get(sourceFile.fileName) || (yield* makeImportablePackagesMetadata(sourceFile));
|
|
3624
3762
|
importablePackagesMetadataCache.set(sourceFile.fileName, packagesMetadata);
|
|
3625
|
-
const formatContext = ts.formatting.getFormatContext(
|
|
3626
|
-
formatOptions || {},
|
|
3627
|
-
languageServiceHost
|
|
3628
|
-
);
|
|
3629
3763
|
const isExcluded = packagesMetadata.isExcludedFromNamespaceImport(
|
|
3630
3764
|
fileName,
|
|
3631
3765
|
exportName
|
|
3632
3766
|
);
|
|
3633
3767
|
if (isExcluded) return applicableCompletionEntryDetails;
|
|
3768
|
+
const asBarrelImport = packagesMetadata.getBarreledModulePath(fileName);
|
|
3769
|
+
if (asBarrelImport) {
|
|
3770
|
+
const codeActions = yield* getImportFromBarrelCodeActions(
|
|
3771
|
+
formatOptions,
|
|
3772
|
+
preferences,
|
|
3773
|
+
languageServiceHost,
|
|
3774
|
+
sourceFile,
|
|
3775
|
+
effectReplaceSpan,
|
|
3776
|
+
asBarrelImport.packageName,
|
|
3777
|
+
asBarrelImport.exportName
|
|
3778
|
+
);
|
|
3779
|
+
return {
|
|
3780
|
+
...applicableCompletionEntryDetails,
|
|
3781
|
+
codeActions
|
|
3782
|
+
};
|
|
3783
|
+
}
|
|
3634
3784
|
const effectUnbarreledModulePath = packagesMetadata.getUnbarreledModulePath(
|
|
3635
3785
|
fileName,
|
|
3636
3786
|
exportName
|
|
3637
3787
|
);
|
|
3638
|
-
const
|
|
3788
|
+
const asNamespaceImport = packagesMetadata.getImportNamespaceByFileName(
|
|
3639
3789
|
effectUnbarreledModulePath || fileName
|
|
3640
3790
|
);
|
|
3641
|
-
if (
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
),
|
|
3666
|
-
ts.factory.createStringLiteral(newModuleSpecifier)
|
|
3667
|
-
),
|
|
3668
|
-
true,
|
|
3669
|
-
preferences || {}
|
|
3670
|
-
);
|
|
3671
|
-
if (!effectUnbarreledModulePath) {
|
|
3672
|
-
changeTracker.insertText(
|
|
3673
|
-
sourceFile,
|
|
3674
|
-
effectReplaceSpan.start,
|
|
3675
|
-
effectNamespaceName + "."
|
|
3676
|
-
);
|
|
3677
|
-
}
|
|
3678
|
-
}
|
|
3679
|
-
);
|
|
3680
|
-
return {
|
|
3681
|
-
...applicableCompletionEntryDetails,
|
|
3682
|
-
codeActions: [
|
|
3683
|
-
{
|
|
3684
|
-
description: "Import * as " + effectNamespaceName + " from " + newModuleSpecifier,
|
|
3685
|
-
changes
|
|
3686
|
-
}
|
|
3687
|
-
]
|
|
3688
|
-
};
|
|
3791
|
+
if (asNamespaceImport) {
|
|
3792
|
+
const newModuleSpecifier = effectUnbarreledModulePath ? getModuleSpecifier(
|
|
3793
|
+
program.getCompilerOptions(),
|
|
3794
|
+
sourceFile,
|
|
3795
|
+
sourceFile.fileName,
|
|
3796
|
+
String(effectUnbarreledModulePath || fileName),
|
|
3797
|
+
program
|
|
3798
|
+
) : moduleSpecifier;
|
|
3799
|
+
const codeActions = yield* getImportFromNamespaceCodeActions(
|
|
3800
|
+
formatOptions,
|
|
3801
|
+
preferences,
|
|
3802
|
+
languageServiceHost,
|
|
3803
|
+
sourceFile,
|
|
3804
|
+
effectReplaceSpan,
|
|
3805
|
+
asNamespaceImport,
|
|
3806
|
+
effectUnbarreledModulePath,
|
|
3807
|
+
newModuleSpecifier
|
|
3808
|
+
);
|
|
3809
|
+
return {
|
|
3810
|
+
...applicableCompletionEntryDetails,
|
|
3811
|
+
codeActions
|
|
3812
|
+
};
|
|
3813
|
+
}
|
|
3814
|
+
return applicableCompletionEntryDetails;
|
|
3689
3815
|
}
|
|
3690
3816
|
);
|
|
3691
3817
|
|