@effect/language-service 0.23.2 → 0.23.4
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 +1 -1
- package/index.js +133 -63
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +91 -10
- package/transform.js.map +1 -1
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ Few options can be provided alongside the initialization of the Language Service
|
|
|
87
87
|
"goto": true, // controls Effect goto references (default: true)
|
|
88
88
|
"allowedDuplicatedPackages": [], // list of package names that has effect in peer dependencies and are allowed to be duplicated (default: [])
|
|
89
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: [])
|
|
90
|
+
"namespaceImportPackages": [] // package names that should be preferred as imported with namespace imports e.g. ["effect", "@effect/*"] (default: [])
|
|
91
91
|
}
|
|
92
92
|
]
|
|
93
93
|
}
|
package/index.js
CHANGED
|
@@ -831,6 +831,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
|
|
|
831
831
|
}
|
|
832
832
|
return [];
|
|
833
833
|
});
|
|
834
|
+
var dedupe = (self) => dedupeWith(self, equivalence());
|
|
834
835
|
|
|
835
836
|
// src/core/Nano.ts
|
|
836
837
|
function makeInternalSuccess(value) {
|
|
@@ -1029,14 +1030,43 @@ function parsePackageContentNameAndVersionFromScope(v) {
|
|
|
1029
1030
|
if (!isString(name)) return;
|
|
1030
1031
|
if (!isString(version)) return;
|
|
1031
1032
|
const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
|
|
1033
|
+
const referencedPackages = Object.keys({
|
|
1034
|
+
...hasProperty(packageJsonContent, "dependencies") && isObject(packageJsonContent.dependencies) ? packageJsonContent.dependencies : {},
|
|
1035
|
+
...hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) ? packageJsonContent.peerDependencies : {},
|
|
1036
|
+
...hasProperty(packageJsonContent, "devDependencies") && isObject(packageJsonContent.devDependencies) ? packageJsonContent.devDependencies : {}
|
|
1037
|
+
});
|
|
1032
1038
|
return {
|
|
1033
1039
|
name: name.toLowerCase(),
|
|
1034
1040
|
version: version.toLowerCase(),
|
|
1035
1041
|
hasEffectInPeerDependencies,
|
|
1036
1042
|
contents: packageJsonContent,
|
|
1037
|
-
packageDirectory: packageJsonScope.packageDirectory
|
|
1043
|
+
packageDirectory: packageJsonScope.packageDirectory,
|
|
1044
|
+
referencedPackages
|
|
1038
1045
|
};
|
|
1039
1046
|
}
|
|
1047
|
+
var resolveModulePattern = fn("resolveModulePattern")(
|
|
1048
|
+
function* (sourceFile, pattern) {
|
|
1049
|
+
if (pattern.indexOf("*") === -1) return [pattern.toLowerCase()];
|
|
1050
|
+
const ts = yield* service(TypeScriptApi);
|
|
1051
|
+
const packageJsonScope = parsePackageContentNameAndVersionFromScope(sourceFile);
|
|
1052
|
+
const referencedPackages = [];
|
|
1053
|
+
for (const statement of sourceFile.statements) {
|
|
1054
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
1055
|
+
const moduleSpecifier = statement.moduleSpecifier.text.toLowerCase();
|
|
1056
|
+
const packageName = moduleSpecifier.startsWith("@") ? moduleSpecifier.split("/", 2).join("/") : moduleSpecifier.split("/", 1).join("/");
|
|
1057
|
+
referencedPackages.push(packageName);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
return pipe(
|
|
1061
|
+
referencedPackages.concat(packageJsonScope?.referencedPackages || []),
|
|
1062
|
+
dedupe,
|
|
1063
|
+
map3((packageName) => packageName.toLowerCase()),
|
|
1064
|
+
filter(
|
|
1065
|
+
(packageName) => pattern.endsWith("*") && packageName.startsWith(pattern.toLowerCase().substring(0, pattern.length - 1))
|
|
1066
|
+
)
|
|
1067
|
+
);
|
|
1068
|
+
}
|
|
1069
|
+
);
|
|
1040
1070
|
function makeGetModuleSpecifier(ts) {
|
|
1041
1071
|
if (!(hasProperty(ts, "moduleSpecifiers") && hasProperty(ts.moduleSpecifiers, "getModuleSpecifier") && isFunction2(ts.moduleSpecifiers.getModuleSpecifier))) return;
|
|
1042
1072
|
const _internal = ts.moduleSpecifiers.getModuleSpecifier;
|
|
@@ -2631,7 +2661,14 @@ var importFromBarrel = createDiagnostic({
|
|
|
2631
2661
|
const ts = yield* service(TypeScriptApi);
|
|
2632
2662
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2633
2663
|
const program = yield* service(TypeScriptProgram);
|
|
2634
|
-
const
|
|
2664
|
+
const packageNamesToCheck = flatten(
|
|
2665
|
+
yield* all(
|
|
2666
|
+
...languageServicePluginOptions.namespaceImportPackages.map(
|
|
2667
|
+
(packageName) => resolveModulePattern(sourceFile, packageName)
|
|
2668
|
+
)
|
|
2669
|
+
)
|
|
2670
|
+
);
|
|
2671
|
+
const isImportedFromBarrelExport = (element) => {
|
|
2635
2672
|
const getModuleSpecifier = makeGetModuleSpecifier(ts);
|
|
2636
2673
|
const resolveExternalModuleName = makeResolveExternalModuleName(typeChecker);
|
|
2637
2674
|
if (!(getModuleSpecifier && resolveExternalModuleName)) return;
|
|
@@ -2644,7 +2681,7 @@ var importFromBarrel = createDiagnostic({
|
|
|
2644
2681
|
if (!namedBindings) return;
|
|
2645
2682
|
if (!ts.isNamedImports(namedBindings)) return;
|
|
2646
2683
|
const barrelModuleName = importDeclaration.moduleSpecifier.text;
|
|
2647
|
-
if (
|
|
2684
|
+
if (packageNamesToCheck.indexOf(barrelModuleName.toLowerCase()) === -1) return;
|
|
2648
2685
|
const moduleSymbol = resolveExternalModuleName(importDeclaration.moduleSpecifier);
|
|
2649
2686
|
if (!moduleSymbol) return;
|
|
2650
2687
|
if (!moduleSymbol.exports) return;
|
|
@@ -2687,7 +2724,7 @@ var importFromBarrel = createDiagnostic({
|
|
|
2687
2724
|
ts.forEachChild(node, appendNodeToVisit);
|
|
2688
2725
|
continue;
|
|
2689
2726
|
}
|
|
2690
|
-
const result = isImportedFromBarrelExport(node
|
|
2727
|
+
const result = isImportedFromBarrelExport(node);
|
|
2691
2728
|
if (!result) continue;
|
|
2692
2729
|
const { barrelModuleName, importClause, importDeclaration, importedName, namedBindings, unbarrelledFileName } = result;
|
|
2693
2730
|
report({
|
|
@@ -3496,61 +3533,73 @@ var makeImportablePackagesMetadata = fn("makeImportablePackagesMetadata")(functi
|
|
|
3496
3533
|
const excludedByFileName = /* @__PURE__ */ new Map();
|
|
3497
3534
|
const unbarreledModulePathByFileName = /* @__PURE__ */ new Map();
|
|
3498
3535
|
const barreledModulePathByFileName = /* @__PURE__ */ new Map();
|
|
3536
|
+
const barreledFunctionPathByFileName = /* @__PURE__ */ new Map();
|
|
3499
3537
|
const packages = [
|
|
3500
|
-
...languageServicePluginOptions.namespaceImportPackages.map((
|
|
3501
|
-
|
|
3538
|
+
...languageServicePluginOptions.namespaceImportPackages.map((packagePattern) => ({
|
|
3539
|
+
packagePattern,
|
|
3502
3540
|
kind: "namespace"
|
|
3503
3541
|
})),
|
|
3504
|
-
...languageServicePluginOptions.barrelImportPackages.map((
|
|
3505
|
-
|
|
3542
|
+
...languageServicePluginOptions.barrelImportPackages.map((packagePattern) => ({
|
|
3543
|
+
packagePattern,
|
|
3506
3544
|
kind: "barrel"
|
|
3507
3545
|
}))
|
|
3508
3546
|
];
|
|
3509
|
-
for (const { kind,
|
|
3510
|
-
const
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
if (
|
|
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
|
-
}
|
|
3545
|
-
}
|
|
3546
|
-
if (exportClause && ts.isNamedExports(exportClause)) {
|
|
3547
|
-
for (const element of exportClause.elements) {
|
|
3548
|
-
if (!ts.isIdentifier(element.name)) continue;
|
|
3549
|
-
const methodName = element.name.text;
|
|
3547
|
+
for (const { kind, packagePattern } of packages) {
|
|
3548
|
+
for (const packageName of yield* resolveModulePattern(sourceFile, packagePattern)) {
|
|
3549
|
+
const barrelModule = ts.resolveModuleName(packageName, sourceFile.fileName, program.getCompilerOptions(), host);
|
|
3550
|
+
if (barrelModule.resolvedModule) {
|
|
3551
|
+
const barrelPath = barrelModule.resolvedModule.resolvedFileName;
|
|
3552
|
+
const barrelSource = program.getSourceFile(barrelPath) || ts.createSourceFile(barrelPath, host.readFile(barrelPath) || "", sourceFile.languageVersion, true);
|
|
3553
|
+
if (barrelSource) {
|
|
3554
|
+
for (const statement of barrelSource.statements) {
|
|
3555
|
+
if (ts.isExportDeclaration(statement)) {
|
|
3556
|
+
const exportClause = statement.exportClause;
|
|
3557
|
+
const moduleSpecifier = statement.moduleSpecifier;
|
|
3558
|
+
if (moduleSpecifier && ts.isStringLiteral(moduleSpecifier)) {
|
|
3559
|
+
const unbarreledModulePathResolved = ts.resolveModuleName(
|
|
3560
|
+
moduleSpecifier.text,
|
|
3561
|
+
barrelSource.fileName,
|
|
3562
|
+
program.getCompilerOptions(),
|
|
3563
|
+
host
|
|
3564
|
+
);
|
|
3565
|
+
if (unbarreledModulePathResolved.resolvedModule) {
|
|
3566
|
+
const unbarreledModulePath = unbarreledModulePathResolved.resolvedModule.resolvedFileName;
|
|
3567
|
+
if (exportClause && ts.isNamespaceExport(exportClause) && ts.isIdentifier(exportClause.name)) {
|
|
3550
3568
|
if (kind === "namespace") {
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3569
|
+
namespaceByFileName.set(unbarreledModulePath, exportClause.name.text);
|
|
3570
|
+
const existingUnbarreledModulePath = unbarreledModulePathByFileName.get(barrelSource.fileName) || [];
|
|
3571
|
+
existingUnbarreledModulePath.push({
|
|
3572
|
+
fileName: unbarreledModulePath,
|
|
3573
|
+
exportName: exportClause.name.text
|
|
3574
|
+
});
|
|
3575
|
+
unbarreledModulePathByFileName.set(barrelSource.fileName, existingUnbarreledModulePath);
|
|
3576
|
+
}
|
|
3577
|
+
if (kind === "barrel") {
|
|
3578
|
+
barreledModulePathByFileName.set(unbarreledModulePath, {
|
|
3579
|
+
fileName: barrelSource.fileName,
|
|
3580
|
+
exportName: exportClause.name.text,
|
|
3581
|
+
packageName
|
|
3582
|
+
});
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
3585
|
+
if (exportClause && ts.isNamedExports(exportClause)) {
|
|
3586
|
+
for (const element of exportClause.elements) {
|
|
3587
|
+
if (!ts.isIdentifier(element.name)) continue;
|
|
3588
|
+
const methodName = element.name.text;
|
|
3589
|
+
if (kind === "namespace") {
|
|
3590
|
+
const excludedMethods = excludedByFileName.get(methodName) || [];
|
|
3591
|
+
excludedMethods.push(unbarreledModulePath);
|
|
3592
|
+
excludedByFileName.set(methodName, excludedMethods);
|
|
3593
|
+
}
|
|
3594
|
+
if (kind === "barrel") {
|
|
3595
|
+
const previousBarreledFunctionPath = barreledFunctionPathByFileName.get(unbarreledModulePath) || [];
|
|
3596
|
+
previousBarreledFunctionPath.push({
|
|
3597
|
+
fileName: barrelSource.fileName,
|
|
3598
|
+
exportName: methodName,
|
|
3599
|
+
packageName
|
|
3600
|
+
});
|
|
3601
|
+
barreledFunctionPathByFileName.set(unbarreledModulePath, previousBarreledFunctionPath);
|
|
3602
|
+
}
|
|
3554
3603
|
}
|
|
3555
3604
|
}
|
|
3556
3605
|
}
|
|
@@ -3565,7 +3614,8 @@ var makeImportablePackagesMetadata = fn("makeImportablePackagesMetadata")(functi
|
|
|
3565
3614
|
getImportNamespaceByFileName: (fileName) => namespaceByFileName.get(fileName),
|
|
3566
3615
|
isExcludedFromNamespaceImport: (fileName, exportName) => (excludedByFileName.get(exportName) || []).includes(fileName),
|
|
3567
3616
|
getUnbarreledModulePath: (fileName, exportName) => unbarreledModulePathByFileName.get(fileName)?.find((_) => _.exportName === exportName)?.fileName,
|
|
3568
|
-
getBarreledModulePath: (fileName) => barreledModulePathByFileName.get(fileName)
|
|
3617
|
+
getBarreledModulePath: (fileName) => barreledModulePathByFileName.get(fileName),
|
|
3618
|
+
getBarreledFunctionPath: (fileName, exportName) => barreledFunctionPathByFileName.get(fileName)?.find((_) => _.exportName === exportName)
|
|
3569
3619
|
};
|
|
3570
3620
|
});
|
|
3571
3621
|
var appendEffectCompletionEntryData = fn("appendEffectCompletionEntryData")(
|
|
@@ -3665,7 +3715,7 @@ var getImportFromNamespaceCodeActions = fn("getImportFromNamespaceCodeActions")(
|
|
|
3665
3715
|
}
|
|
3666
3716
|
];
|
|
3667
3717
|
});
|
|
3668
|
-
var getImportFromBarrelCodeActions = fn("getImportFromBarrelCodeActions")(function* (formatOptions, preferences, languageServiceHost, sourceFile, effectReplaceSpan, newModuleSpecifier, barrelExportName) {
|
|
3718
|
+
var getImportFromBarrelCodeActions = fn("getImportFromBarrelCodeActions")(function* (formatOptions, preferences, languageServiceHost, sourceFile, effectReplaceSpan, newModuleSpecifier, barrelExportName, shouldPrependExportName) {
|
|
3669
3719
|
const ts = yield* service(TypeScriptApi);
|
|
3670
3720
|
const formatContext = ts.formatting.getFormatContext(
|
|
3671
3721
|
formatOptions || {},
|
|
@@ -3729,11 +3779,13 @@ var getImportFromBarrelCodeActions = fn("getImportFromBarrelCodeActions")(functi
|
|
|
3729
3779
|
preferences || {}
|
|
3730
3780
|
);
|
|
3731
3781
|
}
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3782
|
+
if (shouldPrependExportName) {
|
|
3783
|
+
changeTracker.insertText(
|
|
3784
|
+
sourceFile,
|
|
3785
|
+
effectReplaceSpan.start,
|
|
3786
|
+
barrelExportName + "."
|
|
3787
|
+
);
|
|
3788
|
+
}
|
|
3737
3789
|
}
|
|
3738
3790
|
);
|
|
3739
3791
|
return [
|
|
@@ -3772,16 +3824,34 @@ var postprocessCompletionEntryDetails = fn("postprocessCompletionEntryDetails")(
|
|
|
3772
3824
|
exportName
|
|
3773
3825
|
);
|
|
3774
3826
|
if (isExcluded) return applicableCompletionEntryDetails;
|
|
3775
|
-
const
|
|
3776
|
-
if (
|
|
3827
|
+
const asBarrelFunctionImport = packagesMetadata.getBarreledFunctionPath(fileName, exportName);
|
|
3828
|
+
if (asBarrelFunctionImport) {
|
|
3829
|
+
const codeActions = yield* getImportFromBarrelCodeActions(
|
|
3830
|
+
formatOptions,
|
|
3831
|
+
preferences,
|
|
3832
|
+
languageServiceHost,
|
|
3833
|
+
sourceFile,
|
|
3834
|
+
effectReplaceSpan,
|
|
3835
|
+
asBarrelFunctionImport.packageName,
|
|
3836
|
+
asBarrelFunctionImport.exportName,
|
|
3837
|
+
false
|
|
3838
|
+
);
|
|
3839
|
+
return {
|
|
3840
|
+
...applicableCompletionEntryDetails,
|
|
3841
|
+
codeActions
|
|
3842
|
+
};
|
|
3843
|
+
}
|
|
3844
|
+
const asBarrelModuleImport = packagesMetadata.getBarreledModulePath(fileName);
|
|
3845
|
+
if (asBarrelModuleImport) {
|
|
3777
3846
|
const codeActions = yield* getImportFromBarrelCodeActions(
|
|
3778
3847
|
formatOptions,
|
|
3779
3848
|
preferences,
|
|
3780
3849
|
languageServiceHost,
|
|
3781
3850
|
sourceFile,
|
|
3782
3851
|
effectReplaceSpan,
|
|
3783
|
-
|
|
3784
|
-
|
|
3852
|
+
asBarrelModuleImport.packageName,
|
|
3853
|
+
asBarrelModuleImport.exportName,
|
|
3854
|
+
true
|
|
3785
3855
|
);
|
|
3786
3856
|
return {
|
|
3787
3857
|
...applicableCompletionEntryDetails,
|