@effect/language-service 0.39.0 → 0.40.1
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/cli.js +77 -35
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +110 -13
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +250 -73
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +110 -13
- package/transform.js.map +1 -1
package/index.js
CHANGED
|
@@ -1701,7 +1701,8 @@ var defaults = {
|
|
|
1701
1701
|
topLevelNamedReexports: "ignore",
|
|
1702
1702
|
barrelImportPackages: [],
|
|
1703
1703
|
importAliases: {},
|
|
1704
|
-
renames: true
|
|
1704
|
+
renames: true,
|
|
1705
|
+
noExternal: false
|
|
1705
1706
|
};
|
|
1706
1707
|
function parse(config) {
|
|
1707
1708
|
return {
|
|
@@ -1718,7 +1719,8 @@ function parse(config) {
|
|
|
1718
1719
|
barrelImportPackages: isObject(config) && hasProperty(config, "barrelImportPackages") && isArray(config.barrelImportPackages) && config.barrelImportPackages.every(isString) ? config.barrelImportPackages.map((_) => _.toLowerCase()) : defaults.barrelImportPackages,
|
|
1719
1720
|
importAliases: isObject(config) && hasProperty(config, "importAliases") && isRecord(config.importAliases) ? map4(config.importAliases, (value) => String(value)) : defaults.importAliases,
|
|
1720
1721
|
topLevelNamedReexports: isObject(config) && hasProperty(config, "topLevelNamedReexports") && isString(config.topLevelNamedReexports) && ["ignore", "follow"].includes(config.topLevelNamedReexports.toLowerCase()) ? config.topLevelNamedReexports.toLowerCase() : defaults.topLevelNamedReexports,
|
|
1721
|
-
renames: isObject(config) && hasProperty(config, "renames") && isBoolean(config.renames) ? config.renames : defaults.renames
|
|
1722
|
+
renames: isObject(config) && hasProperty(config, "renames") && isBoolean(config.renames) ? config.renames : defaults.renames,
|
|
1723
|
+
noExternal: isObject(config) && hasProperty(config, "noExternal") && isBoolean(config.noExternal) ? config.noExternal : defaults.noExternal
|
|
1722
1724
|
};
|
|
1723
1725
|
}
|
|
1724
1726
|
|
|
@@ -2561,13 +2563,28 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
|
|
|
2561
2563
|
);
|
|
2562
2564
|
const importedSchemaModule = cachedBy(
|
|
2563
2565
|
fn("TypeParser.importedSchemaModule")(function* (node) {
|
|
2566
|
+
if (!ts.isIdentifier(node)) {
|
|
2567
|
+
return yield* typeParserIssue("Node is not an expression", void 0, node);
|
|
2568
|
+
}
|
|
2564
2569
|
const type = typeChecker.getTypeAtLocation(node);
|
|
2565
2570
|
const propertySymbol = typeChecker.getPropertyOfType(type, "Class");
|
|
2566
2571
|
if (!propertySymbol) {
|
|
2567
2572
|
return yield* typeParserIssue("Type has no 'Class' property", type, node);
|
|
2568
2573
|
}
|
|
2569
|
-
|
|
2570
|
-
|
|
2574
|
+
const sourceFile = tsUtils.getSourceFileOfNode(node);
|
|
2575
|
+
if (!sourceFile) {
|
|
2576
|
+
return yield* typeParserIssue("Node is not in a source file", void 0, node);
|
|
2577
|
+
}
|
|
2578
|
+
const schemaIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2579
|
+
sourceFile,
|
|
2580
|
+
"effect",
|
|
2581
|
+
"Schema"
|
|
2582
|
+
);
|
|
2583
|
+
if (!schemaIdentifier) {
|
|
2584
|
+
return yield* typeParserIssue("Schema module not found", void 0, node);
|
|
2585
|
+
}
|
|
2586
|
+
if (ts.idText(node) !== schemaIdentifier) {
|
|
2587
|
+
return yield* typeParserIssue("Node is not a schema module reference", void 0, node);
|
|
2571
2588
|
}
|
|
2572
2589
|
return node;
|
|
2573
2590
|
}),
|
|
@@ -2581,8 +2598,23 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
|
|
|
2581
2598
|
if (!propertySymbol) {
|
|
2582
2599
|
return yield* typeParserIssue("Type has no 'Tag' property", type, node);
|
|
2583
2600
|
}
|
|
2584
|
-
if (!ts.
|
|
2585
|
-
return yield* typeParserIssue("Node is not an
|
|
2601
|
+
if (!ts.isIdentifier(node)) {
|
|
2602
|
+
return yield* typeParserIssue("Node is not an identifier", type, node);
|
|
2603
|
+
}
|
|
2604
|
+
const sourceFile = tsUtils.getSourceFileOfNode(node);
|
|
2605
|
+
if (!sourceFile) {
|
|
2606
|
+
return yield* typeParserIssue("Node is not in a source file", void 0, node);
|
|
2607
|
+
}
|
|
2608
|
+
const contextIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2609
|
+
sourceFile,
|
|
2610
|
+
"effect",
|
|
2611
|
+
"Context"
|
|
2612
|
+
);
|
|
2613
|
+
if (!contextIdentifier) {
|
|
2614
|
+
return yield* typeParserIssue("Context module not found", void 0, node);
|
|
2615
|
+
}
|
|
2616
|
+
if (ts.idText(node) !== contextIdentifier) {
|
|
2617
|
+
return yield* typeParserIssue("Node is not a context module reference", void 0, node);
|
|
2586
2618
|
}
|
|
2587
2619
|
return node;
|
|
2588
2620
|
}),
|
|
@@ -2613,9 +2645,24 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
|
|
|
2613
2645
|
if (!propertySymbol) {
|
|
2614
2646
|
return yield* typeParserIssue("Type has no 'TaggedError' property", type, node);
|
|
2615
2647
|
}
|
|
2616
|
-
if (!ts.
|
|
2648
|
+
if (!ts.isIdentifier(node)) {
|
|
2617
2649
|
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2618
2650
|
}
|
|
2651
|
+
const sourceFile = tsUtils.getSourceFileOfNode(node);
|
|
2652
|
+
if (!sourceFile) {
|
|
2653
|
+
return yield* typeParserIssue("Node is not in a source file", void 0, node);
|
|
2654
|
+
}
|
|
2655
|
+
const dataIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2656
|
+
sourceFile,
|
|
2657
|
+
"effect",
|
|
2658
|
+
"Data"
|
|
2659
|
+
);
|
|
2660
|
+
if (!dataIdentifier) {
|
|
2661
|
+
return yield* typeParserIssue("Data module not found", void 0, node);
|
|
2662
|
+
}
|
|
2663
|
+
if (ts.idText(node) !== dataIdentifier) {
|
|
2664
|
+
return yield* typeParserIssue("Node is not a data module reference", void 0, node);
|
|
2665
|
+
}
|
|
2619
2666
|
return node;
|
|
2620
2667
|
}),
|
|
2621
2668
|
"TypeParser.importedDataModule",
|
|
@@ -2978,8 +3025,10 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
|
|
|
2978
3025
|
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2979
3026
|
const schemaIdentifier = schemaCall.expression;
|
|
2980
3027
|
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && ts.idText(schemaIdentifier.name) === "Class") {
|
|
3028
|
+
const expressionType = typeChecker.getTypeAtLocation(expression);
|
|
2981
3029
|
const parsedSchemaModule = yield* pipe(
|
|
2982
|
-
|
|
3030
|
+
effectSchemaType(expressionType, expression),
|
|
3031
|
+
flatMap(() => importedSchemaModule(schemaIdentifier.expression)),
|
|
2983
3032
|
option
|
|
2984
3033
|
);
|
|
2985
3034
|
if (isSome2(parsedSchemaModule)) {
|
|
@@ -3019,8 +3068,10 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
|
|
|
3019
3068
|
const selfTypeNode = schemaTaggedClassTCall.typeArguments[0];
|
|
3020
3069
|
const schemaIdentifier = schemaTaggedClassTCall.expression;
|
|
3021
3070
|
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && ts.idText(schemaIdentifier.name) === "TaggedClass") {
|
|
3071
|
+
const expressionType = typeChecker.getTypeAtLocation(expression);
|
|
3022
3072
|
const parsedSchemaModule = yield* pipe(
|
|
3023
|
-
|
|
3073
|
+
effectSchemaType(expressionType, expression),
|
|
3074
|
+
flatMap(() => importedSchemaModule(schemaIdentifier.expression)),
|
|
3024
3075
|
option
|
|
3025
3076
|
);
|
|
3026
3077
|
if (isSome2(parsedSchemaModule)) {
|
|
@@ -3062,8 +3113,10 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
|
|
|
3062
3113
|
const selfTypeNode = schemaTaggedErrorTCall.typeArguments[0];
|
|
3063
3114
|
const schemaIdentifier = schemaTaggedErrorTCall.expression;
|
|
3064
3115
|
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && ts.idText(schemaIdentifier.name) === "TaggedError") {
|
|
3116
|
+
const expressionType = typeChecker.getTypeAtLocation(expression);
|
|
3065
3117
|
const parsedSchemaModule = yield* pipe(
|
|
3066
|
-
|
|
3118
|
+
effectSchemaType(expressionType, expression),
|
|
3119
|
+
flatMap(() => importedSchemaModule(schemaIdentifier.expression)),
|
|
3067
3120
|
option
|
|
3068
3121
|
);
|
|
3069
3122
|
if (isSome2(parsedSchemaModule)) {
|
|
@@ -3181,8 +3234,10 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
|
|
|
3181
3234
|
const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
|
|
3182
3235
|
const schemaIdentifier = schemaTaggedRequestTCall.expression;
|
|
3183
3236
|
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && ts.idText(schemaIdentifier.name) === "TaggedRequest") {
|
|
3237
|
+
const expressionType = typeChecker.getTypeAtLocation(expression);
|
|
3184
3238
|
const parsedSchemaModule = yield* pipe(
|
|
3185
|
-
|
|
3239
|
+
effectSchemaType(expressionType, expression),
|
|
3240
|
+
flatMap(() => importedSchemaModule(schemaIdentifier.expression)),
|
|
3186
3241
|
option
|
|
3187
3242
|
);
|
|
3188
3243
|
if (isSome2(parsedSchemaModule)) {
|
|
@@ -3444,7 +3499,10 @@ var generate = fn("writeTagClassAccessors.generate")(function* (sourceFile, serv
|
|
|
3444
3499
|
]
|
|
3445
3500
|
);
|
|
3446
3501
|
return ts.factory.createPropertyDeclaration(
|
|
3447
|
-
[
|
|
3502
|
+
[
|
|
3503
|
+
ts.factory.createModifier(ts.SyntaxKind.StaticKeyword),
|
|
3504
|
+
ts.factory.createModifier(ts.SyntaxKind.OverrideKeyword)
|
|
3505
|
+
],
|
|
3448
3506
|
propertyName,
|
|
3449
3507
|
void 0,
|
|
3450
3508
|
type,
|
|
@@ -3801,6 +3859,7 @@ var classSelfMismatch = createDiagnostic({
|
|
|
3801
3859
|
const result = yield* pipe(
|
|
3802
3860
|
typeParser.extendsEffectService(node),
|
|
3803
3861
|
orElse2(() => typeParser.extendsContextTag(node)),
|
|
3862
|
+
orElse2(() => typeParser.extendsEffectTag(node)),
|
|
3804
3863
|
orElse2(() => typeParser.extendsSchemaClass(node)),
|
|
3805
3864
|
orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
|
|
3806
3865
|
orElse2(() => typeParser.extendsSchemaTaggedError(node)),
|
|
@@ -3809,7 +3868,7 @@ var classSelfMismatch = createDiagnostic({
|
|
|
3809
3868
|
);
|
|
3810
3869
|
if (result) {
|
|
3811
3870
|
const { className, selfTypeNode } = result;
|
|
3812
|
-
let actualName =
|
|
3871
|
+
let actualName = sourceFile.text.substring(selfTypeNode.pos, selfTypeNode.end);
|
|
3813
3872
|
if (ts.isTypeReferenceNode(selfTypeNode)) {
|
|
3814
3873
|
if (ts.isIdentifier(selfTypeNode.typeName)) {
|
|
3815
3874
|
actualName = ts.idText(selfTypeNode.typeName);
|
|
@@ -3893,6 +3952,43 @@ ${versions.map((version) => `- found ${version} at ${resolvedPackages[packageNam
|
|
|
3893
3952
|
})
|
|
3894
3953
|
});
|
|
3895
3954
|
|
|
3955
|
+
// src/diagnostics/effectGenUsesAdapter.ts
|
|
3956
|
+
var effectGenUsesAdapter = createDiagnostic({
|
|
3957
|
+
name: "effectGenUsesAdapter",
|
|
3958
|
+
code: 23,
|
|
3959
|
+
severity: "warning",
|
|
3960
|
+
apply: fn("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
|
|
3961
|
+
const ts = yield* service(TypeScriptApi);
|
|
3962
|
+
const typeParser = yield* service(TypeParser);
|
|
3963
|
+
const nodeToVisit = [];
|
|
3964
|
+
const appendNodeToVisit = (node) => {
|
|
3965
|
+
nodeToVisit.push(node);
|
|
3966
|
+
return void 0;
|
|
3967
|
+
};
|
|
3968
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
3969
|
+
while (nodeToVisit.length > 0) {
|
|
3970
|
+
const node = nodeToVisit.shift();
|
|
3971
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
3972
|
+
if (ts.isCallExpression(node)) {
|
|
3973
|
+
yield* pipe(
|
|
3974
|
+
typeParser.effectGen(node),
|
|
3975
|
+
map3(({ generatorFunction }) => {
|
|
3976
|
+
if (generatorFunction.parameters.length > 0) {
|
|
3977
|
+
const adapter = generatorFunction.parameters[0];
|
|
3978
|
+
report({
|
|
3979
|
+
location: adapter,
|
|
3980
|
+
messageText: `The adapter of Effect.gen is not required anymore, it is now just an alias of pipe.`,
|
|
3981
|
+
fixes: []
|
|
3982
|
+
});
|
|
3983
|
+
}
|
|
3984
|
+
}),
|
|
3985
|
+
ignore
|
|
3986
|
+
);
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
})
|
|
3990
|
+
});
|
|
3991
|
+
|
|
3896
3992
|
// src/diagnostics/effectInVoidSuccess.ts
|
|
3897
3993
|
var effectInVoidSuccess = createDiagnostic({
|
|
3898
3994
|
name: "effectInVoidSuccess",
|
|
@@ -5410,6 +5506,7 @@ var unsupportedServiceAccessors = createDiagnostic({
|
|
|
5410
5506
|
var diagnostics = [
|
|
5411
5507
|
classSelfMismatch,
|
|
5412
5508
|
duplicatePackage,
|
|
5509
|
+
effectGenUsesAdapter,
|
|
5413
5510
|
missingEffectContext,
|
|
5414
5511
|
missingEffectError,
|
|
5415
5512
|
missingEffectServiceDependency,
|
|
@@ -10996,13 +11093,8 @@ function processNodeMermaid(graph, ctx, ctxL) {
|
|
|
10996
11093
|
}
|
|
10997
11094
|
});
|
|
10998
11095
|
}
|
|
10999
|
-
function generateMarmaidUri(
|
|
11096
|
+
function generateMarmaidUri(code) {
|
|
11000
11097
|
return gen(function* () {
|
|
11001
|
-
const ctx = {
|
|
11002
|
-
seenIds: /* @__PURE__ */ new Set()
|
|
11003
|
-
};
|
|
11004
|
-
const lines = yield* processNodeMermaid(graph, ctx, ctxL);
|
|
11005
|
-
const code = "flowchart TB\n" + lines.join("\n");
|
|
11006
11098
|
const state = JSON.stringify({ code });
|
|
11007
11099
|
const data = new TextEncoder().encode(state);
|
|
11008
11100
|
const compressed = deflate_1(data, { level: 9 });
|
|
@@ -11010,75 +11102,110 @@ function generateMarmaidUri(graph, ctxL) {
|
|
|
11010
11102
|
return "https://www.mermaidchart.com/play#" + pakoString;
|
|
11011
11103
|
});
|
|
11012
11104
|
}
|
|
11105
|
+
function getAdjustedNode(sourceFile, position) {
|
|
11106
|
+
return gen(function* () {
|
|
11107
|
+
const ts = yield* service(TypeScriptApi);
|
|
11108
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
11109
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
11110
|
+
const typeParser = yield* service(TypeParser);
|
|
11111
|
+
const range = tsUtils.toTextRange(position);
|
|
11112
|
+
const maybeNode = pipe(
|
|
11113
|
+
tsUtils.getAncestorNodesInRange(sourceFile, range),
|
|
11114
|
+
filter((_) => ts.isVariableDeclaration(_) || ts.isPropertyDeclaration(_)),
|
|
11115
|
+
filter((_) => tsUtils.isNodeInRange(range)(_.name)),
|
|
11116
|
+
head
|
|
11117
|
+
);
|
|
11118
|
+
if (isNone2(maybeNode)) return void 0;
|
|
11119
|
+
const node = maybeNode.value;
|
|
11120
|
+
const layerNode = node.initializer ? node.initializer : node;
|
|
11121
|
+
const layerType = typeChecker.getTypeAtLocation(layerNode);
|
|
11122
|
+
const maybeLayer = yield* option(typeParser.layerType(layerType, layerNode));
|
|
11123
|
+
if (isNone2(maybeLayer)) return void 0;
|
|
11124
|
+
return { node, layerNode };
|
|
11125
|
+
});
|
|
11126
|
+
}
|
|
11127
|
+
function parseLayerGraph(sourceFile, layerNode) {
|
|
11128
|
+
return gen(function* () {
|
|
11129
|
+
const ts = yield* service(TypeScriptApi);
|
|
11130
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
11131
|
+
let lastId = 0;
|
|
11132
|
+
const graphCtx = {
|
|
11133
|
+
services: /* @__PURE__ */ new Map(),
|
|
11134
|
+
serviceTypeToString: /* @__PURE__ */ new Map(),
|
|
11135
|
+
nextId: () => "id" + lastId++
|
|
11136
|
+
};
|
|
11137
|
+
const rootNode = yield* processLayerGraphNode(graphCtx, layerNode, void 0);
|
|
11138
|
+
const ctx = {
|
|
11139
|
+
seenIds: /* @__PURE__ */ new Set()
|
|
11140
|
+
};
|
|
11141
|
+
const mermaidLines = yield* processNodeMermaid(rootNode, ctx, graphCtx);
|
|
11142
|
+
const mermaidCode = "flowchart TB\n" + mermaidLines.join("\n");
|
|
11143
|
+
const textualExplanation = [];
|
|
11144
|
+
const appendInfo = (providesNode, type, kindText) => {
|
|
11145
|
+
const typeString = typeChecker.typeToString(
|
|
11146
|
+
type,
|
|
11147
|
+
void 0,
|
|
11148
|
+
ts.TypeFormatFlags.NoTruncation
|
|
11149
|
+
);
|
|
11150
|
+
const positions = providesNode.map((_) => {
|
|
11151
|
+
const nodePosition = _.node.getStart(sourceFile, false);
|
|
11152
|
+
const { character, line } = ts.getLineAndCharacterOfPosition(sourceFile, nodePosition);
|
|
11153
|
+
const nodeText = _.node.getText().trim().replace(/\n/g, " ").substr(0, 50);
|
|
11154
|
+
return "ln " + (line + 1) + " col " + character + " by `" + nodeText + "`";
|
|
11155
|
+
});
|
|
11156
|
+
textualExplanation.push("- " + typeString + " " + kindText + " at " + positions.join(", "));
|
|
11157
|
+
};
|
|
11158
|
+
for (const providesKey of rootNode.rout) {
|
|
11159
|
+
const providesNode = findInnermostGraphEdge(rootNode, "rout", providesKey);
|
|
11160
|
+
appendInfo(providesNode, graphCtx.services.get(providesKey), "provided");
|
|
11161
|
+
}
|
|
11162
|
+
if (textualExplanation.length > 0) textualExplanation.push("");
|
|
11163
|
+
for (const requiresKey of rootNode.rin) {
|
|
11164
|
+
const requiresNode = findInnermostGraphEdge(rootNode, "rin", requiresKey);
|
|
11165
|
+
appendInfo(requiresNode, graphCtx.services.get(requiresKey), "required");
|
|
11166
|
+
}
|
|
11167
|
+
return { mermaidCode, textualExplanation };
|
|
11168
|
+
});
|
|
11169
|
+
}
|
|
11170
|
+
function effectApiGetLayerGraph(sourceFile, line, character) {
|
|
11171
|
+
return pipe(
|
|
11172
|
+
gen(function* () {
|
|
11173
|
+
const ts = yield* service(TypeScriptApi);
|
|
11174
|
+
const position = ts.getPositionOfLineAndCharacter(sourceFile, line, character);
|
|
11175
|
+
const maybeNodes = yield* getAdjustedNode(sourceFile, position);
|
|
11176
|
+
if (!maybeNodes) return yield* fail(new UnableToProduceLayerGraphError("No node found"));
|
|
11177
|
+
const { layerNode, node } = maybeNodes;
|
|
11178
|
+
const { mermaidCode } = yield* parseLayerGraph(sourceFile, layerNode);
|
|
11179
|
+
return { start: node.pos, end: node.end, mermaidCode };
|
|
11180
|
+
})
|
|
11181
|
+
);
|
|
11182
|
+
}
|
|
11013
11183
|
function layerInfo(sourceFile, position, quickInfo2) {
|
|
11014
11184
|
return pipe(
|
|
11015
11185
|
gen(function* () {
|
|
11016
11186
|
const ts = yield* service(TypeScriptApi);
|
|
11017
|
-
const
|
|
11018
|
-
const
|
|
11019
|
-
|
|
11020
|
-
const
|
|
11021
|
-
const maybeNode = pipe(
|
|
11022
|
-
tsUtils.getAncestorNodesInRange(sourceFile, range),
|
|
11023
|
-
filter((_) => ts.isVariableDeclaration(_) || ts.isPropertyDeclaration(_)),
|
|
11024
|
-
filter((_) => tsUtils.isNodeInRange(range)(_.name)),
|
|
11025
|
-
head
|
|
11026
|
-
);
|
|
11027
|
-
if (isNone2(maybeNode)) return quickInfo2;
|
|
11028
|
-
const node = maybeNode.value;
|
|
11029
|
-
const layerNode = node.initializer ? node.initializer : node;
|
|
11030
|
-
const layerType = typeChecker.getTypeAtLocation(layerNode);
|
|
11031
|
-
const maybeLayer = yield* option(typeParser.layerType(layerType, layerNode));
|
|
11032
|
-
if (isNone2(maybeLayer)) return quickInfo2;
|
|
11033
|
-
let lastId = 0;
|
|
11034
|
-
const graphCtx = {
|
|
11035
|
-
services: /* @__PURE__ */ new Map(),
|
|
11036
|
-
serviceTypeToString: /* @__PURE__ */ new Map(),
|
|
11037
|
-
nextId: () => "id" + lastId++
|
|
11038
|
-
};
|
|
11187
|
+
const options = yield* service(LanguageServicePluginOptions);
|
|
11188
|
+
const maybeNodes = yield* getAdjustedNode(sourceFile, position);
|
|
11189
|
+
if (!maybeNodes) return quickInfo2;
|
|
11190
|
+
const { layerNode, node } = maybeNodes;
|
|
11039
11191
|
const layerInfoDisplayParts = yield* pipe(
|
|
11040
|
-
|
|
11192
|
+
parseLayerGraph(sourceFile, layerNode),
|
|
11041
11193
|
flatMap(
|
|
11042
|
-
(
|
|
11043
|
-
yield* succeed(void 0);
|
|
11044
|
-
const lines = [];
|
|
11045
|
-
const appendInfo = (providesNode, type, kindText) => {
|
|
11046
|
-
const typeString = typeChecker.typeToString(
|
|
11047
|
-
type,
|
|
11048
|
-
void 0,
|
|
11049
|
-
ts.TypeFormatFlags.NoTruncation
|
|
11050
|
-
);
|
|
11051
|
-
const positions = providesNode.map((_) => {
|
|
11052
|
-
const nodePosition = _.node.getStart(sourceFile, false);
|
|
11053
|
-
const { character, line } = ts.getLineAndCharacterOfPosition(sourceFile, nodePosition);
|
|
11054
|
-
const nodeText = _.node.getText().trim().replace(/\n/g, " ").substr(0, 50);
|
|
11055
|
-
return "ln " + (line + 1) + " col " + character + " by `" + nodeText + "`";
|
|
11056
|
-
});
|
|
11057
|
-
lines.push("- " + typeString + " " + kindText + " at " + positions.join(", "));
|
|
11058
|
-
};
|
|
11059
|
-
for (const providesKey of rootNode.rout) {
|
|
11060
|
-
const providesNode = findInnermostGraphEdge(rootNode, "rout", providesKey);
|
|
11061
|
-
appendInfo(providesNode, graphCtx.services.get(providesKey), "provided");
|
|
11062
|
-
}
|
|
11063
|
-
if (lines.length > 0) lines.push("");
|
|
11064
|
-
for (const requiresKey of rootNode.rin) {
|
|
11065
|
-
const requiresNode = findInnermostGraphEdge(rootNode, "rin", requiresKey);
|
|
11066
|
-
appendInfo(requiresNode, graphCtx.services.get(requiresKey), "required");
|
|
11067
|
-
}
|
|
11068
|
-
const mermaidUri = yield* option(generateMarmaidUri(rootNode, graphCtx));
|
|
11194
|
+
({ mermaidCode, textualExplanation }) => gen(function* () {
|
|
11069
11195
|
const linkParts = [];
|
|
11070
|
-
if (
|
|
11196
|
+
if (!options.noExternal) {
|
|
11197
|
+
const mermaidUri = yield* generateMarmaidUri(mermaidCode);
|
|
11071
11198
|
linkParts.push({ kind: "space", text: "\n" });
|
|
11072
11199
|
linkParts.push({ kind: "link", text: "{@link " });
|
|
11073
|
-
linkParts.push({ kind: "linkText", text: mermaidUri
|
|
11200
|
+
linkParts.push({ kind: "linkText", text: mermaidUri + " Show full Layer graph" });
|
|
11074
11201
|
linkParts.push({ kind: "link", text: "}" });
|
|
11075
11202
|
linkParts.push({ kind: "space", text: "\n" });
|
|
11076
11203
|
}
|
|
11077
|
-
if (
|
|
11204
|
+
if (textualExplanation.length === 0) return linkParts;
|
|
11078
11205
|
return [
|
|
11079
11206
|
{
|
|
11080
11207
|
kind: "text",
|
|
11081
|
-
text: "```\n/**\n" +
|
|
11208
|
+
text: "```\n/**\n" + textualExplanation.map((l) => " * " + l).join("\n") + "\n */\n```\n"
|
|
11082
11209
|
},
|
|
11083
11210
|
...linkParts
|
|
11084
11211
|
];
|
|
@@ -13570,6 +13697,56 @@ var init = (modules) => {
|
|
|
13570
13697
|
}
|
|
13571
13698
|
return applicableRenameInfo;
|
|
13572
13699
|
};
|
|
13700
|
+
const additionalProtocolHandlers = {
|
|
13701
|
+
"_effectGetLayerMermaid": (arg) => {
|
|
13702
|
+
const { character, line, path } = arg.arguments;
|
|
13703
|
+
const normalizedPath = modules.typescript.server.toNormalizedPath(path);
|
|
13704
|
+
const projectService = info.project.projectService;
|
|
13705
|
+
const scriptInfo = projectService.getScriptInfoForNormalizedPath(normalizedPath);
|
|
13706
|
+
if (scriptInfo) {
|
|
13707
|
+
const targetProject = scriptInfo.getDefaultProject();
|
|
13708
|
+
if (targetProject) {
|
|
13709
|
+
const program = targetProject.getLanguageService().getProgram();
|
|
13710
|
+
if (program) {
|
|
13711
|
+
const sourceFile = targetProject.getSourceFile(scriptInfo.path);
|
|
13712
|
+
if (sourceFile) {
|
|
13713
|
+
return pipe(
|
|
13714
|
+
effectApiGetLayerGraph(sourceFile, line, character),
|
|
13715
|
+
map3((response) => ({
|
|
13716
|
+
response: {
|
|
13717
|
+
success: true,
|
|
13718
|
+
...response
|
|
13719
|
+
}
|
|
13720
|
+
})),
|
|
13721
|
+
runNano(program),
|
|
13722
|
+
getOrElse((e) => ({
|
|
13723
|
+
response: {
|
|
13724
|
+
success: false,
|
|
13725
|
+
error: e.message
|
|
13726
|
+
}
|
|
13727
|
+
}))
|
|
13728
|
+
);
|
|
13729
|
+
}
|
|
13730
|
+
}
|
|
13731
|
+
}
|
|
13732
|
+
}
|
|
13733
|
+
return {
|
|
13734
|
+
response: {
|
|
13735
|
+
success: false,
|
|
13736
|
+
error: "No source file found"
|
|
13737
|
+
}
|
|
13738
|
+
};
|
|
13739
|
+
}
|
|
13740
|
+
};
|
|
13741
|
+
if (info.session) {
|
|
13742
|
+
for (const [key, value] of Object.entries(additionalProtocolHandlers)) {
|
|
13743
|
+
try {
|
|
13744
|
+
info.session.addProtocolHandler(key, value);
|
|
13745
|
+
} catch (e) {
|
|
13746
|
+
info.project.log("[@effect/language-service] Skipped adding " + key + " protocol handler due to error: " + e);
|
|
13747
|
+
}
|
|
13748
|
+
}
|
|
13749
|
+
}
|
|
13573
13750
|
return proxy;
|
|
13574
13751
|
}
|
|
13575
13752
|
return { create, onConfigurationChanged };
|