@effect/language-service 0.50.0 → 0.51.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/index.js CHANGED
@@ -7076,7 +7076,12 @@ var missedPipeableOpportunity = createDiagnostic({
7076
7076
  "pipe"
7077
7077
  ),
7078
7078
  void 0,
7079
- parentChain.filter(ts.isCallExpression).map((call) => call.expression)
7079
+ pipe(
7080
+ parentChain,
7081
+ filter(ts.isCallExpression),
7082
+ map4((call) => call.expression),
7083
+ reverse
7084
+ )
7080
7085
  )
7081
7086
  );
7082
7087
  })
@@ -8077,6 +8082,50 @@ var strictBooleanExpressions = createDiagnostic({
8077
8082
  })
8078
8083
  });
8079
8084
 
8085
+ // src/diagnostics/strictEffectProvide.ts
8086
+ var strictEffectProvide = createDiagnostic({
8087
+ name: "strictEffectProvide",
8088
+ code: 27,
8089
+ severity: "off",
8090
+ apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
8091
+ const ts = yield* service(TypeScriptApi);
8092
+ const typeChecker = yield* service(TypeCheckerApi);
8093
+ const typeParser = yield* service(TypeParser);
8094
+ const parseEffectProvideWithLayer = (node) => gen(function* () {
8095
+ if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression) || !ts.isIdentifier(node.expression.name) || ts.idText(node.expression.name) !== "provide" || node.arguments.length === 0) {
8096
+ return yield* typeParserIssue("Not an Effect.provide call");
8097
+ }
8098
+ yield* typeParser.importedEffectModule(node.expression.expression);
8099
+ return yield* firstSuccessOf(
8100
+ node.arguments.map((arg) => {
8101
+ const argType = typeChecker.getTypeAtLocation(arg);
8102
+ return typeParser.layerType(argType, arg);
8103
+ })
8104
+ );
8105
+ });
8106
+ const nodeToVisit = [];
8107
+ const appendNodeToVisit = (node) => {
8108
+ nodeToVisit.push(node);
8109
+ return void 0;
8110
+ };
8111
+ ts.forEachChild(sourceFile, appendNodeToVisit);
8112
+ while (nodeToVisit.length > 0) {
8113
+ const node = nodeToVisit.shift();
8114
+ ts.forEachChild(node, appendNodeToVisit);
8115
+ if (ts.isCallExpression(node)) {
8116
+ const layerCheck = yield* pipe(parseEffectProvideWithLayer(node), option);
8117
+ if (isSome2(layerCheck)) {
8118
+ report({
8119
+ location: node,
8120
+ messageText: "Effect.provide with a Layer should only be used at application entry points. If this is an entry point, you can safely disable this diagnostic. Otherwise, using Effect.provide may break scope lifetimes. Compose all layers at your entry point and provide them at once.",
8121
+ fixes: []
8122
+ });
8123
+ }
8124
+ }
8125
+ }
8126
+ })
8127
+ });
8128
+
8080
8129
  // src/diagnostics/tryCatchInEffectGen.ts
8081
8130
  var tryCatchInEffectGen = createDiagnostic({
8082
8131
  name: "tryCatchInEffectGen",
@@ -8367,7 +8416,8 @@ var diagnostics = [
8367
8416
  unsupportedServiceAccessors,
8368
8417
  nonObjectEffectServiceType,
8369
8418
  deterministicKeys,
8370
- missedPipeableOpportunity
8419
+ missedPipeableOpportunity,
8420
+ strictEffectProvide
8371
8421
  ];
8372
8422
 
8373
8423
  // src/completions/effectDiagnosticsComment.ts
@@ -13885,11 +13935,20 @@ var extractLayerGraph = fn("extractLayerGraph")(function* (node, opts) {
13885
13935
  });
13886
13936
  var formatLayerGraph = fn("formatLayerGraph")(function* (layerGraph) {
13887
13937
  const tsUtils = yield* service(TypeScriptUtils);
13938
+ const typeChecker = yield* service(TypeCheckerApi);
13939
+ const ts = yield* service(TypeScriptApi);
13888
13940
  return toMermaid(layerGraph, {
13889
13941
  edgeLabel: (edge) => JSON.stringify(edge),
13890
13942
  nodeLabel: (graphNode) => {
13891
13943
  const sourceFile = tsUtils.getSourceFileOfNode(graphNode.node);
13892
- return sourceFile.text.substring(graphNode.node.pos, graphNode.node.end).trim();
13944
+ let text = sourceFile.text.substring(graphNode.node.pos, graphNode.node.end).trim();
13945
+ text += "\nprovides: " + graphNode.provides.map((_) => typeChecker.typeToString(_, void 0, ts.TypeFormatFlags.NoTruncation)).join(
13946
+ ", "
13947
+ );
13948
+ text += "\nrequires: " + graphNode.requires.map((_) => typeChecker.typeToString(_, void 0, ts.TypeFormatFlags.NoTruncation)).join(
13949
+ ", "
13950
+ );
13951
+ return text;
13893
13952
  }
13894
13953
  });
13895
13954
  });
@@ -13970,7 +14029,7 @@ var formatNestedLayerGraph = fn("formatNestedLayerGraph")(function* (layerGraph)
13970
14029
  var extractOutlineGraph = fn("extractOutlineGraph")(function* (layerGraph) {
13971
14030
  const typeChecker = yield* service(TypeCheckerApi);
13972
14031
  const mutableGraph = beginMutation3(directed());
13973
- const providers = /* @__PURE__ */ new WeakMap();
14032
+ const providers = /* @__PURE__ */ new Map();
13974
14033
  const knownSymbols = /* @__PURE__ */ new WeakSet();
13975
14034
  const leafNodes = values2(externals(layerGraph, { direction: "outgoing" }));
13976
14035
  const dedupedLeafNodes = [];
@@ -13997,8 +14056,12 @@ var extractOutlineGraph = fn("extractOutlineGraph")(function* (layerGraph) {
13997
14056
  }
13998
14057
  for (const [nodeIndex, nodeInfo] of entries(nodes(mutableGraph))) {
13999
14058
  for (const requiredType of nodeInfo.requires) {
14000
- for (const providerNodeIndex of providers.get(requiredType) || []) {
14001
- addEdge(mutableGraph, nodeIndex, providerNodeIndex, {});
14059
+ for (const [providedType, providerNodeIndexes] of providers.entries()) {
14060
+ if (requiredType === providedType || typeChecker.isTypeAssignableTo(requiredType, providedType)) {
14061
+ for (const providerNodeIndex of providerNodeIndexes) {
14062
+ addEdge(mutableGraph, nodeIndex, providerNodeIndex, {});
14063
+ }
14064
+ }
14002
14065
  }
14003
14066
  }
14004
14067
  }
@@ -14085,7 +14148,8 @@ var walkLeavesMatching = (graph, predicate, config = {}) => {
14085
14148
  var extractProvidersAndRequirers = fn("extractProvidersAndRequirers")(
14086
14149
  function* (layerGraph) {
14087
14150
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
14088
- const rootWalker = externals(layerGraph, { direction: "outgoing" });
14151
+ const typeChecker = yield* service(TypeCheckerApi);
14152
+ const rootWalker = externals(layerGraph, { direction: "incoming" });
14089
14153
  const rootNodes = fromIterable(values2(rootWalker));
14090
14154
  const rootNodeIndexes = fromIterable(indices(rootWalker));
14091
14155
  const result = [];
@@ -14096,7 +14160,9 @@ var extractProvidersAndRequirers = fn("extractProvidersAndRequirers")(
14096
14160
  for (const layerNode of values2(
14097
14161
  walkLeavesMatching(
14098
14162
  layerGraph,
14099
- (_) => (kind === "provided" ? _.provides : _.requires).indexOf(layerType) > -1,
14163
+ (_) => (kind === "provided" ? _.provides : _.requires).some(
14164
+ (_2) => _2 === layerType || typeChecker.isTypeAssignableTo(_2, layerType)
14165
+ ),
14100
14166
  { start: rootNodeIndexes }
14101
14167
  )
14102
14168
  )) {