@effect/language-service 0.17.1 → 0.19.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/transform.js CHANGED
@@ -24,7 +24,7 @@ __export(transform_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(transform_exports);
26
26
 
27
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Function.js
27
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Function.js
28
28
  var isFunction = (input) => typeof input === "function";
29
29
  var dual = function(arity, body) {
30
30
  if (typeof arity === "function") {
@@ -118,11 +118,11 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
118
118
  }
119
119
  }
120
120
 
121
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/internal/version.js
122
- var moduleVersion = "3.12.5";
121
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/version.js
122
+ var moduleVersion = "3.16.3";
123
123
  var getCurrentVersion = () => moduleVersion;
124
124
 
125
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/GlobalValue.js
125
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/GlobalValue.js
126
126
  var globalStoreId = `effect/GlobalValue/globalStoreId/${/* @__PURE__ */ getCurrentVersion()}`;
127
127
  var globalStore;
128
128
  var globalValue = (id, compute) => {
@@ -136,16 +136,19 @@ var globalValue = (id, compute) => {
136
136
  return globalStore.get(id);
137
137
  };
138
138
 
139
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Predicate.js
139
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Predicate.js
140
+ var isString = (input) => typeof input === "string";
141
+ var isNumber = (input) => typeof input === "number";
142
+ var isBoolean = (input) => typeof input === "boolean";
140
143
  var isFunction2 = isFunction;
141
144
  var isRecordOrArray = (input) => typeof input === "object" && input !== null;
142
145
  var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
143
146
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
144
147
 
145
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/internal/errors.js
148
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/errors.js
146
149
  var getBugErrorMessage = (message) => `BUG: ${message} - please report an issue at https://github.com/Effect-TS/effect/issues`;
147
150
 
148
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Utils.js
151
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Utils.js
149
152
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
150
153
  var isGenKind = (u) => isObject(u) && GenKindTypeId in u;
151
154
  var GenKindImpl = class {
@@ -256,10 +259,25 @@ var structuralRegionState = /* @__PURE__ */ globalValue("effect/Utils/isStructur
256
259
  enabled: false,
257
260
  tester: void 0
258
261
  }));
262
+ var standard = {
263
+ effect_internal_function: (body) => {
264
+ return body();
265
+ }
266
+ };
267
+ var forced = {
268
+ effect_internal_function: (body) => {
269
+ try {
270
+ return body();
271
+ } finally {
272
+ }
273
+ }
274
+ };
275
+ var isNotOptimizedAway = /* @__PURE__ */ standard.effect_internal_function(() => new Error().stack)?.includes("effect_internal_function") === true;
276
+ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forced.effect_internal_function;
259
277
  var genConstructor = function* () {
260
278
  }.constructor;
261
279
 
262
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Hash.js
280
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Hash.js
263
281
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
264
282
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
265
283
  var hash = (self) => {
@@ -285,6 +303,8 @@ var hash = (self) => {
285
303
  return string("null");
286
304
  } else if (self instanceof Date) {
287
305
  return hash(self.toISOString());
306
+ } else if (self instanceof URL) {
307
+ return hash(self.href);
288
308
  } else if (isHash(self)) {
289
309
  return self[symbol]();
290
310
  } else {
@@ -356,7 +376,7 @@ var cached = function() {
356
376
  return hash2;
357
377
  };
358
378
 
359
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Equal.js
379
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Equal.js
360
380
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
361
381
  function equals() {
362
382
  if (arguments.length === 1) {
@@ -382,6 +402,8 @@ function compareBoth(self, that) {
382
402
  }
383
403
  } else if (self instanceof Date && that instanceof Date) {
384
404
  return self.toISOString() === that.toISOString();
405
+ } else if (self instanceof URL && that instanceof URL) {
406
+ return self.href === that.href;
385
407
  }
386
408
  }
387
409
  if (structuralRegionState.enabled) {
@@ -407,7 +429,7 @@ function compareBoth(self, that) {
407
429
  }
408
430
  var isEqual = (u) => hasProperty(u, symbol2);
409
431
 
410
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Inspectable.js
432
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Inspectable.js
411
433
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
412
434
  var toJSON = (x) => {
413
435
  try {
@@ -416,7 +438,7 @@ var toJSON = (x) => {
416
438
  } else if (Array.isArray(x)) {
417
439
  return x.map(toJSON);
418
440
  }
419
- } catch (_) {
441
+ } catch {
420
442
  return {};
421
443
  }
422
444
  return redact(x);
@@ -459,7 +481,7 @@ var redact = (u) => {
459
481
  return u;
460
482
  };
461
483
 
462
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Pipeable.js
484
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Pipeable.js
463
485
  var pipeArguments = (self, args) => {
464
486
  switch (args.length) {
465
487
  case 0:
@@ -492,10 +514,10 @@ var pipeArguments = (self, args) => {
492
514
  }
493
515
  };
494
516
 
495
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/internal/opCodes/effect.js
517
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/opCodes/effect.js
496
518
  var OP_COMMIT = "Commit";
497
519
 
498
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/internal/effectable.js
520
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/effectable.js
499
521
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
500
522
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
501
523
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -582,7 +604,7 @@ var StructuralCommitPrototype = {
582
604
  ...StructuralPrototype
583
605
  };
584
606
 
585
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/internal/option.js
607
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/option.js
586
608
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
587
609
  var CommonProto = {
588
610
  ...EffectPrototype,
@@ -640,7 +662,7 @@ var some = (value) => {
640
662
  return a;
641
663
  };
642
664
 
643
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/internal/either.js
665
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/either.js
644
666
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
645
667
  var CommonProto2 = {
646
668
  ...EffectPrototype,
@@ -702,7 +724,7 @@ var right = (right3) => {
702
724
  return a;
703
725
  };
704
726
 
705
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Either.js
727
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Either.js
706
728
  var right2 = right;
707
729
  var left2 = left;
708
730
  var isLeft2 = isLeft;
@@ -710,17 +732,25 @@ var isRight2 = isRight;
710
732
  var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
711
733
  var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
712
734
 
713
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Order.js
735
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Order.js
714
736
  var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
715
737
 
716
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Option.js
738
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Option.js
717
739
  var none2 = () => none;
718
740
  var some2 = some;
719
741
  var isNone2 = isNone;
720
742
  var isSome2 = isSome;
743
+ var match = /* @__PURE__ */ dual(2, (self, {
744
+ onNone,
745
+ onSome
746
+ }) => isNone2(self) ? onNone() : onSome(self.value));
747
+ var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
748
+ var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
721
749
 
722
- // node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Array.js
750
+ // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Array.js
723
751
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
752
+ var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
753
+ var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
724
754
  var isArray = Array.isArray;
725
755
  var isEmptyArray = (self) => self.length === 0;
726
756
  var isEmptyReadonlyArray = isEmptyArray;
@@ -729,6 +759,7 @@ var sort = /* @__PURE__ */ dual(2, (self, O) => {
729
759
  out.sort(O);
730
760
  return out;
731
761
  });
762
+ var empty = () => [];
732
763
  var map2 = /* @__PURE__ */ dual(2, (self, f) => self.map(f));
733
764
  var flatMap = /* @__PURE__ */ dual(2, (self, f) => {
734
765
  if (isEmptyReadonlyArray(self)) {
@@ -836,7 +867,7 @@ var map3 = dual(2, (fa, f) => make2((ctx) => {
836
867
  if (result._tag !== "Right") return result;
837
868
  return makeInternalSuccess(f(result.value));
838
869
  }));
839
- var orElse = (f) => (fa) => make2((ctx) => {
870
+ var orElse2 = (f) => (fa) => make2((ctx) => {
840
871
  const result = fa.run(ctx);
841
872
  if (result._tag === "Left") return f(result.value).run(ctx);
842
873
  return result;
@@ -891,6 +922,17 @@ var option = (fa) => make2((ctx) => {
891
922
  }
892
923
  });
893
924
 
925
+ // src/core/LanguageServicePluginOptions.ts
926
+ var LanguageServicePluginOptions = Tag("PluginOptions");
927
+ function parse(config) {
928
+ return {
929
+ diagnostics: isObject(config) && hasProperty(config, "diagnostics") && isBoolean(config.diagnostics) ? config.diagnostics : true,
930
+ quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : true,
931
+ completions: isObject(config) && hasProperty(config, "completions") && isBoolean(config.completions) ? config.completions : true,
932
+ allowedDuplicatedPackages: isObject(config) && hasProperty(config, "allowedDuplicatedPackages") && isArray(config.allowedDuplicatedPackages) && config.allowedDuplicatedPackages.every(isString) ? config.allowedDuplicatedPackages.map((_) => _.toLowerCase()) : []
933
+ };
934
+ }
935
+
894
936
  // src/core/TypeScriptApi.ts
895
937
  var TypeScriptApi = Tag("TypeScriptApi");
896
938
  var TypeScriptProgram = Tag("TypeScriptProgram");
@@ -903,26 +945,17 @@ var RefactorNotApplicableError = class {
903
945
  function createDiagnostic(definition) {
904
946
  return definition;
905
947
  }
906
- function parsePluginOptions(config) {
907
- return {
908
- diagnostics: config && "diagnostics" in config && typeof config.diagnostics === "boolean" ? config.diagnostics : true,
909
- quickinfo: config && "quickinfo" in config && typeof config.quickinfo === "boolean" ? config.quickinfo : true,
910
- completions: config && "completions" in config && typeof config.completions === "boolean" ? config.completions : true,
911
- multipleEffectCheck: config && "multipleEffectCheck" in config && typeof config.multipleEffectCheck === "boolean" ? config.multipleEffectCheck : true
912
- };
913
- }
914
- var PluginOptions = Tag("PluginOptions");
915
948
  var getSemanticDiagnosticsWithCodeFixes = fn(
916
949
  "LSP.getSemanticDiagnosticsWithCodeFixes"
917
950
  )(function* (rules, sourceFile) {
918
- const effectDiagnostics = [];
919
- const effectCodeFixes = [];
951
+ let effectDiagnostics = [];
952
+ let effectCodeFixes = [];
920
953
  const executor = yield* createDiagnosticExecutor(sourceFile);
921
954
  for (const rule of rules) {
922
955
  const result = yield* option(executor.execute(rule));
923
956
  if (isSome2(result)) {
924
- effectDiagnostics.push(
925
- ...pipe(
957
+ effectDiagnostics = effectDiagnostics.concat(
958
+ pipe(
926
959
  result.value,
927
960
  map2((_) => ({
928
961
  file: sourceFile,
@@ -935,8 +968,8 @@ var getSemanticDiagnosticsWithCodeFixes = fn(
935
968
  }))
936
969
  )
937
970
  );
938
- effectCodeFixes.push(
939
- ...pipe(
971
+ effectCodeFixes = effectCodeFixes.concat(
972
+ pipe(
940
973
  result.value,
941
974
  map2(
942
975
  (_) => map2(
@@ -959,6 +992,9 @@ var getSemanticDiagnosticsWithCodeFixes = fn(
959
992
  codeFixes: effectCodeFixes
960
993
  };
961
994
  });
995
+ function refactorNameToFullyQualifiedName(name) {
996
+ return `@effect/language-service/refactors/${name}`;
997
+ }
962
998
  var getApplicableRefactors = fn("LSP.getApplicableRefactors")(function* (refactors, sourceFile, positionOrRange) {
963
999
  const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
964
1000
  const effectRefactors = [];
@@ -966,10 +1002,10 @@ var getApplicableRefactors = fn("LSP.getApplicableRefactors")(function* (refacto
966
1002
  const result = yield* option(refactor.apply(sourceFile, textRange));
967
1003
  if (isSome2(result)) {
968
1004
  effectRefactors.push({
969
- name: refactor.name,
1005
+ name: refactorNameToFullyQualifiedName(refactor.name),
970
1006
  description: refactor.description,
971
1007
  actions: [{
972
- name: refactor.name,
1008
+ name: refactorNameToFullyQualifiedName(refactor.name),
973
1009
  description: result.value.description,
974
1010
  kind: result.value.kind
975
1011
  }]
@@ -979,7 +1015,7 @@ var getApplicableRefactors = fn("LSP.getApplicableRefactors")(function* (refacto
979
1015
  return effectRefactors;
980
1016
  });
981
1017
  var getEditsForRefactor = fn("LSP.getEditsForRefactor")(function* (refactors, sourceFile, positionOrRange, refactorName) {
982
- const refactor = refactors.find((refactor2) => refactor2.name === refactorName);
1018
+ const refactor = refactors.find((refactor2) => refactorNameToFullyQualifiedName(refactor2.name) === refactorName);
983
1019
  if (!refactor) {
984
1020
  return yield* fail(new RefactorNotApplicableError());
985
1021
  }
@@ -987,11 +1023,11 @@ var getEditsForRefactor = fn("LSP.getEditsForRefactor")(function* (refactors, so
987
1023
  return yield* refactor.apply(sourceFile, textRange);
988
1024
  });
989
1025
  var getCompletionsAtPosition = fn("LSP.getCompletionsAtPosition")(function* (completions, sourceFile, position, options, formatCodeSettings) {
990
- const effectCompletions = [];
1026
+ let effectCompletions = [];
991
1027
  for (const completion of completions) {
992
1028
  const result = yield* completion.apply(sourceFile, position, options, formatCodeSettings);
993
- effectCompletions.push(
994
- ...result.map((_) => ({ sortText: "11", ..._ }))
1029
+ effectCompletions = effectCompletions.concat(
1030
+ result.map((_) => ({ sortText: "11", ..._ }))
995
1031
  );
996
1032
  }
997
1033
  return effectCompletions;
@@ -999,27 +1035,74 @@ var getCompletionsAtPosition = fn("LSP.getCompletionsAtPosition")(function* (com
999
1035
  var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1000
1036
  function* (sourceFile) {
1001
1037
  const ts = yield* service(TypeScriptApi);
1002
- const ruleOverrides = {};
1038
+ function findNodeWithLeadingCommentAtPosition(position) {
1039
+ const sourceText = sourceFile.text;
1040
+ let result;
1041
+ function find(node) {
1042
+ const leading = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
1043
+ if (leading) {
1044
+ for (const r of leading) {
1045
+ if (r.pos <= position && position < r.end) {
1046
+ result = node;
1047
+ return;
1048
+ }
1049
+ }
1050
+ }
1051
+ if (node.getFullStart() <= position && position < node.getEnd()) {
1052
+ node.forEachChild(find);
1053
+ }
1054
+ }
1055
+ find(sourceFile);
1056
+ return result;
1057
+ }
1058
+ function findParentStatementForDisableNextLine(node) {
1059
+ let result;
1060
+ function find(node2) {
1061
+ if (ts.isStatement(node2)) {
1062
+ result = node2;
1063
+ return;
1064
+ }
1065
+ if (result) return;
1066
+ if (node2.parent) find(node2.parent);
1067
+ }
1068
+ find(node);
1069
+ return result || node;
1070
+ }
1071
+ const lineOverrides = {};
1072
+ const sectionOverrides = {};
1003
1073
  const skippedRules = [];
1004
- const regex = /@effect-diagnostics((?:\s[a-zA-Z0-9/]+:(?:off|warning|error|message|suggestion|skip-file))+)?/gm;
1005
- let match;
1006
- while ((match = regex.exec(sourceFile.text)) !== null) {
1007
- const rulesCaptureGroup = match[1];
1074
+ const regex = /@effect-diagnostics(-next-line)?((?:\s[a-zA-Z0-9/]+:(?:off|warning|error|message|suggestion|skip-file))+)?/gm;
1075
+ let match2;
1076
+ while ((match2 = regex.exec(sourceFile.text)) !== null) {
1077
+ const nextLineCaptureGroup = match2[1];
1078
+ const rulesCaptureGroup = match2[2];
1008
1079
  if (rulesCaptureGroup) {
1009
1080
  const trimmedRuleString = rulesCaptureGroup.trim();
1010
1081
  if (trimmedRuleString) {
1011
1082
  const individualRules = trimmedRuleString.split(/\s+/);
1012
1083
  for (const rulePair of individualRules) {
1013
- const [ruleName, ruleLevel] = rulePair.toLowerCase().split(":");
1084
+ const [rawRuleName, ruleLevel] = rulePair.toLowerCase().split(":");
1085
+ const ruleName = rawRuleName.startsWith("effect/") ? rawRuleName.substring("effect/".length) : rawRuleName;
1014
1086
  if (ruleName && ruleLevel) {
1015
1087
  if (ruleLevel === "skip-file") skippedRules.push(ruleName);
1016
- ruleOverrides[ruleName] = ruleOverrides[ruleName] || [];
1017
- const newLength = ruleOverrides[ruleName].push({
1018
- start: match.index,
1019
- end: Number.MAX_SAFE_INTEGER,
1020
- level: ruleLevel
1021
- });
1022
- if (newLength > 1) ruleOverrides[ruleName][newLength - 2].end = match.index;
1088
+ const isOverrideNextLine = nextLineCaptureGroup && nextLineCaptureGroup.trim().toLowerCase() === "-next-line";
1089
+ if (isOverrideNextLine) {
1090
+ const node = findNodeWithLeadingCommentAtPosition(match2.index);
1091
+ if (node) {
1092
+ lineOverrides[ruleName] = lineOverrides[ruleName] || [];
1093
+ lineOverrides[ruleName].unshift({
1094
+ pos: node.getFullStart(),
1095
+ end: node.end,
1096
+ level: ruleLevel
1097
+ });
1098
+ }
1099
+ } else {
1100
+ sectionOverrides[ruleName] = sectionOverrides[ruleName] || [];
1101
+ sectionOverrides[ruleName].unshift({
1102
+ pos: match2.index,
1103
+ level: ruleLevel
1104
+ });
1105
+ }
1023
1106
  }
1024
1107
  }
1025
1108
  }
@@ -1035,22 +1118,46 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1035
1118
  const ruleNameLowered = rule.name.toLowerCase();
1036
1119
  if (skippedRules.indexOf(ruleNameLowered) > -1) return [];
1037
1120
  let modifiedDiagnostics = yield* rule.apply(sourceFile);
1038
- for (const override of ruleOverrides[ruleNameLowered] || []) {
1039
- if (override.level === "off") {
1040
- modifiedDiagnostics = modifiedDiagnostics.filter(
1041
- (_) => !(_.node.getStart(sourceFile) >= override.start && _.node.getEnd() <= override.end)
1121
+ for (const emitted of modifiedDiagnostics.slice(0)) {
1122
+ let newLevel = void 0;
1123
+ if (!(ruleNameLowered in sectionOverrides || ruleNameLowered in lineOverrides)) continue;
1124
+ const lineOverride = (lineOverrides[ruleNameLowered] || []).find(
1125
+ (_) => _.pos < emitted.node.getStart(sourceFile) && _.end >= emitted.node.getEnd()
1126
+ );
1127
+ if (lineOverride) {
1128
+ newLevel = lineOverride.level;
1129
+ } else {
1130
+ const sectionOverride = (sectionOverrides[ruleNameLowered] || []).find(
1131
+ (_) => _.pos < emitted.node.getStart(sourceFile)
1042
1132
  );
1133
+ if (sectionOverride) newLevel = sectionOverride.level;
1134
+ }
1135
+ if (newLevel === "off") {
1136
+ modifiedDiagnostics = modifiedDiagnostics.filter((_) => _ !== emitted);
1043
1137
  } else {
1044
- for (const message of modifiedDiagnostics.filter(
1045
- (_) => _.node.getStart(sourceFile) >= override.start && _.node.getEnd() <= override.end
1046
- )) {
1047
- message.category = override.level in levelToDiagnosticCategory ? levelToDiagnosticCategory[override.level] : message.category;
1048
- }
1138
+ emitted.category = newLevel && newLevel in levelToDiagnosticCategory ? levelToDiagnosticCategory[newLevel] : emitted.category;
1049
1139
  }
1050
1140
  }
1141
+ const fixByDisableNextLine = (_) => ({
1142
+ fixName: rule.name + "_skipNextLine",
1143
+ description: "Disable " + rule.name + " for this line",
1144
+ apply: flatMap2(
1145
+ service(ChangeTracker),
1146
+ (changeTracker) => sync(() => {
1147
+ const disableAtNode = findParentStatementForDisableNextLine(_.node);
1148
+ const { line } = ts.getLineAndCharacterOfPosition(sourceFile, disableAtNode.getStart());
1149
+ changeTracker.insertCommentBeforeLine(
1150
+ sourceFile,
1151
+ line,
1152
+ disableAtNode.getStart(),
1153
+ ` @effect-diagnostics-next-line ${rule.name}:off`
1154
+ );
1155
+ })
1156
+ )
1157
+ });
1051
1158
  const fixByDisableEntireFile = {
1052
1159
  fixName: rule.name + "_skipFile",
1053
- description: "Disable " + rule.name + " for this file",
1160
+ description: "Disable " + rule.name + " for this entire file",
1054
1161
  apply: flatMap2(
1055
1162
  service(ChangeTracker),
1056
1163
  (changeTracker) => sync(
@@ -1065,7 +1172,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1065
1172
  };
1066
1173
  const rulesWithDisableFix = modifiedDiagnostics.map((diagnostic) => ({
1067
1174
  ...diagnostic,
1068
- fixes: diagnostic.fixes.concat([fixByDisableEntireFile])
1175
+ fixes: diagnostic.fixes.concat([fixByDisableNextLine(diagnostic), fixByDisableEntireFile])
1069
1176
  }));
1070
1177
  return rulesWithDisableFix;
1071
1178
  });
@@ -1097,12 +1204,12 @@ var getMissingTypeEntriesInTargetType = fn(
1097
1204
  function* (realType, expectedType) {
1098
1205
  const typeChecker = yield* service(TypeCheckerApi);
1099
1206
  const result = [];
1100
- const toTest = [realType];
1207
+ let toTest = [realType];
1101
1208
  while (toTest.length > 0) {
1102
1209
  const type = toTest.pop();
1103
1210
  if (!type) return result;
1104
1211
  if (type.isUnion()) {
1105
- toTest.push(...type.types);
1212
+ toTest = toTest.concat(type.types);
1106
1213
  } else {
1107
1214
  const assignable = typeChecker.isTypeAssignableTo(type, expectedType);
1108
1215
  if (!assignable) {
@@ -1278,6 +1385,463 @@ var expectedAndRealType = fn("TypeCheckerApi.expectedAndRealType")(function* (so
1278
1385
  cache.expectedAndRealType.set(sourceFile, result);
1279
1386
  return result;
1280
1387
  });
1388
+ var appendToUniqueTypesMap = fn(
1389
+ "TypeCheckerApi.appendToUniqueTypesMap"
1390
+ )(
1391
+ function* (memory, initialType, excludeNever) {
1392
+ const ts = yield* service(TypeScriptApi);
1393
+ const typeChecker = yield* service(TypeCheckerApi);
1394
+ const newIndexes = /* @__PURE__ */ new Set();
1395
+ const knownIndexes = /* @__PURE__ */ new Set();
1396
+ let toTest = [initialType];
1397
+ while (toTest.length > 0) {
1398
+ const type = toTest.pop();
1399
+ if (!type) break;
1400
+ if (excludeNever && type.flags & ts.TypeFlags.Never) {
1401
+ continue;
1402
+ }
1403
+ if (type.isUnion()) {
1404
+ toTest = toTest.concat(type.types);
1405
+ } else {
1406
+ const foundMatch = [];
1407
+ for (const [typeId, knownType] of memory.entries()) {
1408
+ const areSame = typeChecker.isTypeAssignableTo(knownType, type) && typeChecker.isTypeAssignableTo(type, knownType);
1409
+ if (areSame) {
1410
+ foundMatch.push(typeId);
1411
+ break;
1412
+ }
1413
+ }
1414
+ if (foundMatch.length === 0) {
1415
+ const newId = "t" + (memory.size + 1);
1416
+ memory.set(newId, type);
1417
+ newIndexes.add(newId);
1418
+ } else {
1419
+ knownIndexes.add(foundMatch[0]);
1420
+ }
1421
+ }
1422
+ }
1423
+ return {
1424
+ newIndexes,
1425
+ knownIndexes,
1426
+ allIndexes: pipe(
1427
+ fromIterable(newIndexes),
1428
+ appendAll(fromIterable(knownIndexes))
1429
+ )
1430
+ };
1431
+ }
1432
+ );
1433
+
1434
+ // src/diagnostics/duplicatePackage.ts
1435
+ var checkedPackagesCache = /* @__PURE__ */ new Map();
1436
+ var programResolvedCacheSize = /* @__PURE__ */ new Map();
1437
+ function parsePackageContentNameAndVersion(v) {
1438
+ if (!isObject(v)) return;
1439
+ if (!hasProperty(v, "packageJsonScope")) return;
1440
+ if (!v.packageJsonScope) return;
1441
+ const packageJsonScope = v.packageJsonScope;
1442
+ if (!hasProperty(packageJsonScope, "contents")) return;
1443
+ if (!hasProperty(packageJsonScope.contents, "packageJsonContent")) return;
1444
+ const packageJsonContent = packageJsonScope.contents.packageJsonContent;
1445
+ if (!hasProperty(packageJsonContent, "name")) return;
1446
+ if (!hasProperty(packageJsonContent, "version")) return;
1447
+ const { name, version } = packageJsonContent;
1448
+ if (!isString(name)) return;
1449
+ if (!isString(version)) return;
1450
+ const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
1451
+ return {
1452
+ name: name.toLowerCase(),
1453
+ version: version.toLowerCase(),
1454
+ hasEffectInPeerDependencies,
1455
+ contents: packageJsonContent
1456
+ };
1457
+ }
1458
+ var duplicatePackage = createDiagnostic({
1459
+ name: "duplicatePackage",
1460
+ code: 6,
1461
+ apply: fn("duplicatePackage.apply")(function* (sourceFile) {
1462
+ const ts = yield* service(TypeScriptApi);
1463
+ const program = yield* service(TypeScriptProgram);
1464
+ const options = yield* service(LanguageServicePluginOptions);
1465
+ const effectDiagnostics = [];
1466
+ if (sourceFile.statements.length < 1) return [];
1467
+ let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
1468
+ const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
1469
+ const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
1470
+ if (newResolvedModuleSize !== oldResolvedSize) {
1471
+ const seenPackages = /* @__PURE__ */ new Set();
1472
+ resolvedPackages = {};
1473
+ program.getSourceFiles().map((_) => {
1474
+ const packageInfo = parsePackageContentNameAndVersion(_);
1475
+ if (!packageInfo) return;
1476
+ const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
1477
+ if (seenPackages.has(packageNameAndVersion)) return;
1478
+ seenPackages.add(packageNameAndVersion);
1479
+ if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
1480
+ if (options.allowedDuplicatedPackages.indexOf(packageInfo.name) > -1) return;
1481
+ resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
1482
+ resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.contents;
1483
+ });
1484
+ checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
1485
+ programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
1486
+ }
1487
+ for (const packageName of Object.keys(resolvedPackages)) {
1488
+ if (Object.keys(resolvedPackages[packageName]).length > 1) {
1489
+ const versions = Object.keys(resolvedPackages[packageName]);
1490
+ effectDiagnostics.push({
1491
+ node: sourceFile.statements[0],
1492
+ category: ts.DiagnosticCategory.Warning,
1493
+ messageText: `Package ${packageName} is referenced multiple times with different versions (${versions.join(", ")}) and may cause unexpected type errors.
1494
+ Cleanup your dependencies and your package lockfile to avoid multiple instances of this package and reload the project.
1495
+ If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.stringify(options.allowedDuplicatedPackages.concat([packageName]))}.`,
1496
+ fixes: []
1497
+ });
1498
+ }
1499
+ }
1500
+ return effectDiagnostics;
1501
+ })
1502
+ });
1503
+
1504
+ // src/core/AST.ts
1505
+ function collectSelfAndAncestorNodesInRange(node, textRange) {
1506
+ return sync(() => {
1507
+ let result = empty();
1508
+ let parent = node;
1509
+ while (parent) {
1510
+ if (parent.end >= textRange.end) {
1511
+ result = pipe(result, append(parent));
1512
+ }
1513
+ parent = parent.parent;
1514
+ }
1515
+ return result;
1516
+ });
1517
+ }
1518
+ var getAncestorNodesInRange = fn("AST.getAncestorNodesInRange")(function* (sourceFile, textRange) {
1519
+ const nodeAtPosition = yield* option(findNodeAtPosition(sourceFile, textRange.pos));
1520
+ if (isNone2(nodeAtPosition)) return empty();
1521
+ return yield* collectSelfAndAncestorNodesInRange(nodeAtPosition.value, textRange);
1522
+ });
1523
+ var NodeNotFoundError = class {
1524
+ _tag = "@effect/language-service/NodeNotFoundError";
1525
+ };
1526
+ var findNodeAtPosition = fn("AST.findNodeAtPosition")(function* (sourceFile, position) {
1527
+ const ts = yield* service(TypeScriptApi);
1528
+ function find(node) {
1529
+ if (position >= node.getStart() && position < node.getEnd()) {
1530
+ return ts.forEachChild(node, find) || node;
1531
+ }
1532
+ return void 0;
1533
+ }
1534
+ const result = find(sourceFile);
1535
+ if (!result) return yield* fail(new NodeNotFoundError());
1536
+ return result;
1537
+ });
1538
+ var getCommentAtPosition = fn("TypeScriptApi.getCommentAtPosition")(function* (sourceFile, pos) {
1539
+ const ts = yield* service(TypeScriptApi);
1540
+ const token = yield* findNodeAtPosition(sourceFile, pos);
1541
+ if (token === void 0 || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || "").length) {
1542
+ return yield* fail(new NodeNotFoundError());
1543
+ }
1544
+ const startPos = token.pos === 0 ? (ts.getShebang(sourceFile.text) || "").length : token.pos;
1545
+ if (startPos === 0) return yield* fail(new NodeNotFoundError());
1546
+ const result = ts.forEachTrailingCommentRange(sourceFile.text, startPos, isCommentInRange, pos) || ts.forEachLeadingCommentRange(sourceFile.text, startPos, isCommentInRange, pos);
1547
+ if (!result) return yield* fail(new NodeNotFoundError());
1548
+ return result;
1549
+ });
1550
+ function isCommentInRange(pos, end, kind, _nl, at) {
1551
+ return at >= pos && at < end ? { pos, end, kind } : void 0;
1552
+ }
1553
+ var transformAsyncAwaitToEffectGen = fn("AST.transformAsyncAwaitToEffectGen")(
1554
+ function* (node, effectModuleName, onAwait) {
1555
+ const ts = yield* service(TypeScriptApi);
1556
+ function visitor(_) {
1557
+ if (ts.isAwaitExpression(_)) {
1558
+ const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
1559
+ return ts.factory.createYieldExpression(
1560
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
1561
+ onAwait(expression)
1562
+ );
1563
+ }
1564
+ return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
1565
+ }
1566
+ const generatorBody = visitor(node.body);
1567
+ const effectGenCallExp = yield* createEffectGenCallExpression(effectModuleName, generatorBody);
1568
+ let currentFlags = ts.getCombinedModifierFlags(node);
1569
+ currentFlags &= ~ts.ModifierFlags.Async;
1570
+ const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
1571
+ if (ts.isArrowFunction(node)) {
1572
+ return ts.factory.createArrowFunction(
1573
+ newModifiers,
1574
+ node.typeParameters,
1575
+ node.parameters,
1576
+ void 0,
1577
+ node.equalsGreaterThanToken,
1578
+ effectGenCallExp
1579
+ );
1580
+ }
1581
+ const newBody = ts.factory.createBlock([
1582
+ ts.factory.createReturnStatement(effectGenCallExp)
1583
+ ]);
1584
+ if (ts.isFunctionDeclaration(node)) {
1585
+ return ts.factory.createFunctionDeclaration(
1586
+ newModifiers,
1587
+ node.asteriskToken,
1588
+ node.name,
1589
+ node.typeParameters,
1590
+ node.parameters,
1591
+ void 0,
1592
+ newBody
1593
+ );
1594
+ }
1595
+ return ts.factory.createFunctionExpression(
1596
+ newModifiers,
1597
+ node.asteriskToken,
1598
+ node.name,
1599
+ node.typeParameters,
1600
+ node.parameters,
1601
+ void 0,
1602
+ newBody
1603
+ );
1604
+ }
1605
+ );
1606
+ var addReturnTypeAnnotation = fn("AST.addReturnTypeAnnotation")(function* (sourceFile, declaration, typeNode) {
1607
+ const ts = yield* service(TypeScriptApi);
1608
+ const changes = yield* service(ChangeTracker);
1609
+ const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
1610
+ const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
1611
+ const endNode = needParens ? declaration.parameters[0] : closeParen;
1612
+ if (endNode) {
1613
+ if (needParens) {
1614
+ changes.insertNodeBefore(
1615
+ sourceFile,
1616
+ endNode,
1617
+ ts.factory.createToken(ts.SyntaxKind.OpenParenToken)
1618
+ );
1619
+ changes.insertNodeAfter(
1620
+ sourceFile,
1621
+ endNode,
1622
+ ts.factory.createToken(ts.SyntaxKind.CloseParenToken)
1623
+ );
1624
+ }
1625
+ changes.insertNodeAt(sourceFile, endNode.end, typeNode, { prefix: ": " });
1626
+ }
1627
+ });
1628
+ var removeReturnTypeAnnotation = fn("AST.removeReturnTypeAnnotation")(function* (sourceFile, declaration) {
1629
+ const ts = yield* service(TypeScriptApi);
1630
+ const changes = yield* service(ChangeTracker);
1631
+ const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
1632
+ const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
1633
+ const endNode = needParens ? declaration.parameters[0] : closeParen;
1634
+ if (endNode && declaration.type) {
1635
+ changes.deleteRange(sourceFile, { pos: endNode.end, end: declaration.type.end });
1636
+ }
1637
+ });
1638
+ var ImportModuleIdentifierNotFoundError = class {
1639
+ _tag = "@effect/language-service/ImportModuleIdentifierNotFoundError";
1640
+ };
1641
+ var findImportedModuleIdentifier = fn("AST.findImportedModuleIdentifier")(
1642
+ function* (sourceFile, test) {
1643
+ const ts = yield* service(TypeScriptApi);
1644
+ for (const statement of sourceFile.statements) {
1645
+ if (!ts.isImportDeclaration(statement)) continue;
1646
+ const importClause = statement.importClause;
1647
+ if (!importClause) continue;
1648
+ const namedBindings = importClause.namedBindings;
1649
+ if (!namedBindings) continue;
1650
+ if (ts.isNamespaceImport(namedBindings)) {
1651
+ if (yield* test(namedBindings.name, statement.moduleSpecifier, none2())) {
1652
+ return namedBindings.name;
1653
+ }
1654
+ } else if (ts.isNamedImports(namedBindings)) {
1655
+ for (const importSpecifier of namedBindings.elements) {
1656
+ const importProperty = fromNullable(importSpecifier.propertyName).pipe(
1657
+ orElse(() => some2(importSpecifier.name))
1658
+ );
1659
+ if (yield* test(importSpecifier.name, statement.moduleSpecifier, importProperty)) {
1660
+ return importSpecifier.name;
1661
+ }
1662
+ }
1663
+ }
1664
+ }
1665
+ return yield* fail(new ImportModuleIdentifierNotFoundError());
1666
+ }
1667
+ );
1668
+ function findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, packageName, moduleName) {
1669
+ return findImportedModuleIdentifier(
1670
+ sourceFile,
1671
+ fn(
1672
+ "AST.findImportedModuleIdentifierByPackageAndNameOrBarrel.findImportedModuleIdentifier"
1673
+ )(function* (_, fromModule, importProperty) {
1674
+ const ts = yield* service(TypeScriptApi);
1675
+ if (isNone2(importProperty) && ts.isStringLiteral(fromModule) && fromModule.text === packageName + "/" + moduleName) {
1676
+ return true;
1677
+ }
1678
+ if (isSome2(importProperty) && ts.isIdentifier(importProperty.value) && importProperty.value.text === moduleName && ts.isStringLiteral(fromModule) && fromModule.text === packageName) {
1679
+ return true;
1680
+ }
1681
+ return false;
1682
+ })
1683
+ );
1684
+ }
1685
+ var simplifyTypeNode = fn("AST.simplifyTypeNode")(function* (typeNode) {
1686
+ const ts = yield* service(TypeScriptApi);
1687
+ function collectCallable(typeNode2) {
1688
+ if (ts.isParenthesizedTypeNode(typeNode2)) return collectCallable(typeNode2.type);
1689
+ if (ts.isFunctionTypeNode(typeNode2)) {
1690
+ return some2([
1691
+ ts.factory.createCallSignature(typeNode2.typeParameters, typeNode2.parameters, typeNode2.type)
1692
+ ]);
1693
+ }
1694
+ if (ts.isTypeLiteralNode(typeNode2)) {
1695
+ const allCallSignatures = typeNode2.members.every(ts.isCallSignatureDeclaration);
1696
+ if (allCallSignatures) {
1697
+ return some2(typeNode2.members);
1698
+ }
1699
+ }
1700
+ if (ts.isIntersectionTypeNode(typeNode2)) {
1701
+ const members = typeNode2.types.map((node) => collectCallable(node));
1702
+ if (members.every(isSome2)) {
1703
+ return some2(members.map((_) => isSome2(_) ? _.value : []).flat());
1704
+ }
1705
+ }
1706
+ return none2();
1707
+ }
1708
+ const callSignatures = collectCallable(typeNode);
1709
+ if (isSome2(callSignatures) && callSignatures.value.length > 1) {
1710
+ return ts.factory.createTypeLiteralNode(callSignatures.value);
1711
+ }
1712
+ return typeNode;
1713
+ });
1714
+ var tryPreserveDeclarationSemantics = fn("AST.tryPreserveDeclarationSemantics")(
1715
+ function* (nodeToReplace, node) {
1716
+ const ts = yield* service(TypeScriptApi);
1717
+ if (!ts.isExpression(node)) return node;
1718
+ if (ts.isFunctionDeclaration(nodeToReplace)) {
1719
+ if (!nodeToReplace.name) return node;
1720
+ return ts.factory.createVariableStatement(
1721
+ nodeToReplace.modifiers,
1722
+ ts.factory.createVariableDeclarationList(
1723
+ [ts.factory.createVariableDeclaration(
1724
+ nodeToReplace.name,
1725
+ void 0,
1726
+ void 0,
1727
+ node
1728
+ )],
1729
+ ts.NodeFlags.Const
1730
+ )
1731
+ );
1732
+ } else if (ts.isMethodDeclaration(nodeToReplace)) {
1733
+ return ts.factory.createPropertyDeclaration(
1734
+ nodeToReplace.modifiers,
1735
+ nodeToReplace.name,
1736
+ void 0,
1737
+ void 0,
1738
+ node
1739
+ );
1740
+ }
1741
+ return node;
1742
+ }
1743
+ );
1744
+ var parseAccessedExpressionForCompletion = fn(
1745
+ "AST.parseAccessedExpressionForCompletion"
1746
+ )(
1747
+ function* (sourceFile, position) {
1748
+ const ts = yield* service(TypeScriptApi);
1749
+ const precedingToken = ts.findPrecedingToken(position, sourceFile, void 0, true);
1750
+ if (!precedingToken) return yield* fail(new NodeNotFoundError());
1751
+ let accessedObject = precedingToken;
1752
+ let replacementSpan = ts.createTextSpan(position, 0);
1753
+ let outerNode = precedingToken;
1754
+ if (ts.isIdentifier(precedingToken) && precedingToken.parent && ts.isPropertyAccessExpression(precedingToken.parent)) {
1755
+ replacementSpan = ts.createTextSpan(
1756
+ precedingToken.parent.getStart(sourceFile),
1757
+ precedingToken.end - precedingToken.parent.getStart(sourceFile)
1758
+ );
1759
+ accessedObject = precedingToken.parent.expression;
1760
+ outerNode = precedingToken.parent;
1761
+ } else if (ts.isToken(precedingToken) && precedingToken.kind === ts.SyntaxKind.DotToken && ts.isPropertyAccessExpression(precedingToken.parent)) {
1762
+ replacementSpan = ts.createTextSpan(
1763
+ precedingToken.parent.getStart(sourceFile),
1764
+ precedingToken.end - precedingToken.parent.getStart(sourceFile)
1765
+ );
1766
+ accessedObject = precedingToken.parent.expression;
1767
+ outerNode = precedingToken.parent;
1768
+ } else if (ts.isIdentifier(precedingToken) && precedingToken.parent) {
1769
+ replacementSpan = ts.createTextSpan(
1770
+ precedingToken.getStart(sourceFile),
1771
+ precedingToken.end - precedingToken.getStart(sourceFile)
1772
+ );
1773
+ accessedObject = precedingToken;
1774
+ outerNode = precedingToken;
1775
+ } else {
1776
+ return yield* fail(new NodeNotFoundError());
1777
+ }
1778
+ return { accessedObject, outerNode, replacementSpan };
1779
+ }
1780
+ );
1781
+ var parseDataForExtendsClassCompletion = fn(
1782
+ "AST.parseDataForExtendsClassCompletion"
1783
+ )(function* (sourceFile, position) {
1784
+ const ts = yield* service(TypeScriptApi);
1785
+ const { accessedObject, outerNode, replacementSpan } = yield* parseAccessedExpressionForCompletion(
1786
+ sourceFile,
1787
+ position
1788
+ );
1789
+ if (!ts.isIdentifier(accessedObject)) return yield* fail(new NodeNotFoundError());
1790
+ let classDeclaration = outerNode.parent;
1791
+ while (ts.isExpressionWithTypeArguments(classDeclaration) || ts.isHeritageClause(classDeclaration)) {
1792
+ if (!classDeclaration.parent) break;
1793
+ classDeclaration = classDeclaration.parent;
1794
+ }
1795
+ if (!ts.isClassDeclaration(classDeclaration)) return yield* fail(new NodeNotFoundError());
1796
+ if (!classDeclaration.name) return yield* fail(new NodeNotFoundError());
1797
+ return {
1798
+ accessedObject,
1799
+ classDeclaration,
1800
+ className: classDeclaration.name,
1801
+ replacementSpan
1802
+ };
1803
+ });
1804
+ var createEffectGenCallExpression = fn("AST.createEffectGenCallExpression")(function* (effectModuleIdentifierName, node) {
1805
+ const ts = yield* service(TypeScriptApi);
1806
+ const generator = ts.factory.createFunctionExpression(
1807
+ void 0,
1808
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
1809
+ void 0,
1810
+ [],
1811
+ [],
1812
+ void 0,
1813
+ node
1814
+ // NOTE(mattia): intended, to use same routine for both ConciseBody and Body
1815
+ );
1816
+ return ts.factory.createCallExpression(
1817
+ ts.factory.createPropertyAccessExpression(
1818
+ ts.factory.createIdentifier(effectModuleIdentifierName),
1819
+ "gen"
1820
+ ),
1821
+ void 0,
1822
+ [generator]
1823
+ );
1824
+ });
1825
+ var createEffectGenCallExpressionWithBlock = fn(
1826
+ "AST.createEffectGenCallExpressionWithBlock"
1827
+ )(function* (effectModuleIdentifierName, statement) {
1828
+ const ts = yield* service(TypeScriptApi);
1829
+ return yield* createEffectGenCallExpression(
1830
+ effectModuleIdentifierName,
1831
+ ts.factory.createBlock(Array.isArray(statement) ? statement : [statement], false)
1832
+ );
1833
+ });
1834
+ var createReturnYieldStarStatement = fn("AST.createReturnYieldStarStatement")(
1835
+ function* (expr) {
1836
+ const ts = yield* service(TypeScriptApi);
1837
+ return ts.factory.createReturnStatement(
1838
+ ts.factory.createYieldExpression(
1839
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
1840
+ expr
1841
+ )
1842
+ );
1843
+ }
1844
+ );
1281
1845
 
1282
1846
  // src/utils/TypeParser.ts
1283
1847
  var TypeParserIssue = class {
@@ -1298,6 +1862,13 @@ function covariantTypeArgument(type) {
1298
1862
  }
1299
1863
  return succeed(signatures[0].getReturnType());
1300
1864
  }
1865
+ function contravariantTypeArgument(type) {
1866
+ const signatures = type.getCallSignatures();
1867
+ if (signatures.length !== 1) {
1868
+ return typeParserIssue("Contravariant type has no call signature", type);
1869
+ }
1870
+ return succeed(signatures[0].getTypeParameterAtPosition(0));
1871
+ }
1301
1872
  function invariantTypeArgument(type) {
1302
1873
  const signatures = type.getCallSignatures();
1303
1874
  if (signatures.length !== 1) {
@@ -1329,6 +1900,19 @@ var varianceStructCovariantType = fn("TypeParser.varianceStructCovariantType")(
1329
1900
  return yield* covariantTypeArgument(propertyType);
1330
1901
  }
1331
1902
  );
1903
+ var varianceStructContravariantType = fn(
1904
+ "TypeParser.varianceStructContravariantType"
1905
+ )(
1906
+ function* (type, atLocation, propertyName) {
1907
+ const typeChecker = yield* service(TypeCheckerApi);
1908
+ const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
1909
+ if (!propertySymbol) {
1910
+ return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
1911
+ }
1912
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
1913
+ return yield* contravariantTypeArgument(propertyType);
1914
+ }
1915
+ );
1332
1916
  var varianceStructInvariantType = fn("TypeParser.varianceStructInvariantType")(
1333
1917
  function* (type, atLocation, propertyName) {
1334
1918
  const typeChecker = yield* service(TypeCheckerApi);
@@ -1347,6 +1931,13 @@ var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type
1347
1931
  R: yield* varianceStructCovariantType(type, atLocation, "_R")
1348
1932
  };
1349
1933
  });
1934
+ var layerVarianceStruct = fn("TypeParser.layerVarianceStruct")(function* (type, atLocation) {
1935
+ return {
1936
+ ROut: yield* varianceStructContravariantType(type, atLocation, "_ROut"),
1937
+ E: yield* varianceStructCovariantType(type, atLocation, "_E"),
1938
+ RIn: yield* varianceStructCovariantType(type, atLocation, "_RIn")
1939
+ };
1940
+ });
1350
1941
  var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
1351
1942
  const ts = yield* service(TypeScriptApi);
1352
1943
  const typeChecker = yield* service(TypeCheckerApi);
@@ -1367,6 +1958,26 @@ var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
1367
1958
  }
1368
1959
  return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
1369
1960
  });
1961
+ var layerType = fn("TypeParser.layerType")(function* (type, atLocation) {
1962
+ const ts = yield* service(TypeScriptApi);
1963
+ const typeChecker = yield* service(TypeCheckerApi);
1964
+ yield* pipeableType(type, atLocation);
1965
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
1966
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
1967
+ );
1968
+ propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
1969
+ for (const propertySymbol of propertiesSymbols) {
1970
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
1971
+ const varianceArgs = yield* option(layerVarianceStruct(
1972
+ propertyType,
1973
+ atLocation
1974
+ ));
1975
+ if (isSome2(varianceArgs)) {
1976
+ return varianceArgs.value;
1977
+ }
1978
+ }
1979
+ return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
1980
+ });
1370
1981
  var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
1371
1982
  const typeChecker = yield* service(TypeCheckerApi);
1372
1983
  const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
@@ -1383,9 +1994,10 @@ var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
1383
1994
  var effectSubtype = fn("TypeParser.effectSubtype")(function* (type, atLocation) {
1384
1995
  const typeChecker = yield* service(TypeCheckerApi);
1385
1996
  const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
1386
- if (!tagSymbol) {
1997
+ const getSymbol = typeChecker.getPropertyOfType(type, "get");
1998
+ if (!(tagSymbol || getSymbol)) {
1387
1999
  return yield* typeParserIssue(
1388
- "Type is not a subtype of effect because it does not have '_tag' property",
2000
+ "Type is not a subtype of effect because it does not have '_tag' or 'get' property",
1389
2001
  type,
1390
2002
  atLocation
1391
2003
  );
@@ -1531,19 +2143,68 @@ var effectFnGen = fn("TypeParser.effectFnGen")(function* (node) {
1531
2143
  functionStar: generatorFunction.getFirstToken()
1532
2144
  };
1533
2145
  });
1534
- var returnYieldEffectBlock = fn("TypeParser.returnYieldEffectBlock")(function* (body) {
2146
+ var unnecessaryEffectGen = fn("TypeParser.unnecessaryEffectGen")(function* (node) {
1535
2147
  const ts = yield* service(TypeScriptApi);
1536
2148
  const typeChecker = yield* service(TypeCheckerApi);
1537
- if (ts.isBlock(body) && body.statements.length === 1 && ts.isReturnStatement(body.statements[0]) && body.statements[0].expression && ts.isYieldExpression(body.statements[0].expression) && body.statements[0].expression.expression) {
1538
- const nodeToCheck = body.statements[0].expression.expression;
1539
- const type = typeChecker.getTypeAtLocation(nodeToCheck);
1540
- yield* effectType(type, nodeToCheck);
1541
- return nodeToCheck;
2149
+ const { body } = yield* effectGen(node);
2150
+ if (body.statements.length !== 1) {
2151
+ return yield* typeParserIssue(
2152
+ "Generator body should have a single statement",
2153
+ void 0,
2154
+ node
2155
+ );
2156
+ }
2157
+ let explicitReturn = false;
2158
+ let nodeToCheck = body.statements[0];
2159
+ while (nodeToCheck) {
2160
+ if (ts.isReturnStatement(nodeToCheck) && nodeToCheck.expression) {
2161
+ nodeToCheck = nodeToCheck.expression;
2162
+ explicitReturn = true;
2163
+ continue;
2164
+ }
2165
+ if (ts.isExpressionStatement(nodeToCheck)) {
2166
+ nodeToCheck = nodeToCheck.expression;
2167
+ continue;
2168
+ }
2169
+ if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
2170
+ const yieldedExpression = nodeToCheck.expression;
2171
+ const type = typeChecker.getTypeAtLocation(yieldedExpression);
2172
+ const { A: successType } = yield* effectType(type, yieldedExpression);
2173
+ let replacementNode = succeed(yieldedExpression);
2174
+ if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
2175
+ replacementNode = pipe(
2176
+ gen(function* () {
2177
+ const effectIdentifier = pipe(
2178
+ yield* option(
2179
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(node.getSourceFile(), "effect", "Effect")
2180
+ ),
2181
+ match({
2182
+ onNone: () => "Effect",
2183
+ onSome: (_) => _.text
2184
+ })
2185
+ );
2186
+ return ts.factory.createCallExpression(
2187
+ ts.factory.createPropertyAccessExpression(
2188
+ ts.factory.createIdentifier(effectIdentifier),
2189
+ "asVoid"
2190
+ ),
2191
+ void 0,
2192
+ [
2193
+ yieldedExpression
2194
+ ]
2195
+ );
2196
+ }),
2197
+ provideService(TypeScriptApi, ts)
2198
+ );
2199
+ }
2200
+ return { node, body, yieldedExpression, replacementNode };
2201
+ }
2202
+ break;
1542
2203
  }
1543
2204
  return yield* typeParserIssue(
1544
- "Node is not a return statement with a yield expression",
2205
+ "Not an handled node",
1545
2206
  void 0,
1546
- body
2207
+ node
1547
2208
  );
1548
2209
  });
1549
2210
  var effectSchemaVarianceStruct = fn("TypeParser.effectSchemaVarianceStruct")(
@@ -1580,7 +2241,7 @@ var effectSchemaType = fn("TypeParser.effectSchemaType")(function* (type, atLoca
1580
2241
 
1581
2242
  // src/diagnostics/floatingEffect.ts
1582
2243
  var floatingEffect = createDiagnostic({
1583
- name: "effect/floatingEffect",
2244
+ name: "floatingEffect",
1584
2245
  code: 3,
1585
2246
  apply: fn("floatingEffect.apply")(function* (sourceFile) {
1586
2247
  const ts = yield* service(TypeScriptApi);
@@ -1589,7 +2250,7 @@ var floatingEffect = createDiagnostic({
1589
2250
  if (!ts.isExpressionStatement(node)) return false;
1590
2251
  if (!(ts.isBlock(node.parent) || ts.isSourceFile(node.parent))) return false;
1591
2252
  const expression = node.expression;
1592
- if (ts.isBinaryExpression(expression) && expression.operatorToken && expression.operatorToken.kind === ts.SyntaxKind.EqualsToken) return false;
2253
+ if (ts.isBinaryExpression(expression) && expression.operatorToken && (expression.operatorToken.kind === ts.SyntaxKind.EqualsToken || expression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionEqualsToken || expression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandEqualsToken || expression.operatorToken.kind === ts.SyntaxKind.BarBarEqualsToken)) return false;
1593
2254
  return true;
1594
2255
  }
1595
2256
  const effectDiagnostics = [];
@@ -1608,7 +2269,7 @@ var floatingEffect = createDiagnostic({
1608
2269
  if (isSome2(effect)) {
1609
2270
  const allowedFloatingEffects = yield* pipe(
1610
2271
  fiberType(type, node.expression),
1611
- orElse(() => effectSubtype(type, node.expression)),
2272
+ orElse2(() => effectSubtype(type, node.expression)),
1612
2273
  option
1613
2274
  );
1614
2275
  if (isNone2(allowedFloatingEffects)) {
@@ -1627,7 +2288,7 @@ var floatingEffect = createDiagnostic({
1627
2288
 
1628
2289
  // src/diagnostics/missingEffectContext.ts
1629
2290
  var missingEffectContext = createDiagnostic({
1630
- name: "effect/missingEffectContext",
2291
+ name: "missingEffectContext",
1631
2292
  code: 1,
1632
2293
  apply: fn("missingEffectContext.apply")(function* (sourceFile) {
1633
2294
  const ts = yield* service(TypeScriptApi);
@@ -1660,7 +2321,7 @@ var missingEffectContext = createDiagnostic({
1660
2321
  valueNode,
1661
2322
  realType
1662
2323
  ),
1663
- orElse(() => succeed([]))
2324
+ orElse2(() => succeed([]))
1664
2325
  );
1665
2326
  if (missingContext.length > 0) {
1666
2327
  effectDiagnostics.push(
@@ -1679,7 +2340,7 @@ var missingEffectContext = createDiagnostic({
1679
2340
 
1680
2341
  // src/diagnostics/missingEffectError.ts
1681
2342
  var missingEffectError = createDiagnostic({
1682
- name: "effect/missingEffectError",
2343
+ name: "missingEffectError",
1683
2344
  code: 1,
1684
2345
  apply: fn("missingEffectError.apply")(function* (sourceFile) {
1685
2346
  const ts = yield* service(TypeScriptApi);
@@ -1712,7 +2373,7 @@ var missingEffectError = createDiagnostic({
1712
2373
  valueNode,
1713
2374
  realType
1714
2375
  ),
1715
- orElse(() => succeed([]))
2376
+ orElse2(() => succeed([]))
1716
2377
  );
1717
2378
  if (missingContext.length > 0) {
1718
2379
  effectDiagnostics.push(
@@ -1731,7 +2392,7 @@ var missingEffectError = createDiagnostic({
1731
2392
 
1732
2393
  // src/diagnostics/missingStarInYieldEffectGen.ts
1733
2394
  var missingStarInYieldEffectGen = createDiagnostic({
1734
- name: "effect/missingStarInYieldEffectGen",
2395
+ name: "missingStarInYieldEffectGen",
1735
2396
  code: 4,
1736
2397
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile) {
1737
2398
  const ts = yield* service(TypeScriptApi);
@@ -1750,14 +2411,14 @@ var missingStarInYieldEffectGen = createDiagnostic({
1750
2411
  if (ts.isYieldExpression(node) && node.expression && node.asteriskToken === void 0) {
1751
2412
  const functionStarNode = ts.findAncestor(
1752
2413
  node,
1753
- (_) => (ts.isFunctionExpression(_) || ts.isMethodDeclaration(_)) && _.asteriskToken !== void 0
2414
+ (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_)
1754
2415
  );
1755
2416
  if (functionStarNode && functionStarNode.parent) {
1756
2417
  const effectGenNode = functionStarNode.parent;
1757
2418
  const effectGenLike = yield* pipe(
1758
2419
  effectGen(effectGenNode),
1759
- orElse(() => effectFnUntracedGen(effectGenNode)),
1760
- orElse(() => effectFnGen(effectGenNode)),
2420
+ orElse2(() => effectFnUntracedGen(effectGenNode)),
2421
+ orElse2(() => effectFnGen(effectGenNode)),
1761
2422
  option
1762
2423
  );
1763
2424
  if (isSome2(effectGenLike)) {
@@ -1804,51 +2465,9 @@ var missingStarInYieldEffectGen = createDiagnostic({
1804
2465
  })
1805
2466
  });
1806
2467
 
1807
- // src/diagnostics/multipleEffectVersions.ts
1808
- var effectVersionsCache = /* @__PURE__ */ new Map();
1809
- var programResolvedCacheSize = /* @__PURE__ */ new Map();
1810
- var multipleEffectVersions = createDiagnostic({
1811
- name: "effect/multipleEffectVersions",
1812
- code: 6,
1813
- apply: fn("multipleEffectVersions.apply")(function* (sourceFile) {
1814
- const ts = yield* service(TypeScriptApi);
1815
- const program = yield* service(TypeScriptProgram);
1816
- const options = yield* service(PluginOptions);
1817
- const effectDiagnostics = [];
1818
- if (!options.multipleEffectCheck) return [];
1819
- if (sourceFile.statements.length < 1) return [];
1820
- const effectVersions = effectVersionsCache.get(sourceFile.fileName) || {};
1821
- const newResolvedModuleSize = "resolvedModules" in program && typeof program.resolvedModules === "object" && "size" in program.resolvedModules ? program.resolvedModules.size : 0;
1822
- const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || 0;
1823
- if (newResolvedModuleSize !== oldResolvedSize) {
1824
- if ("forEachResolvedModule" in program && typeof program.forEachResolvedModule === "function") {
1825
- program.forEachResolvedModule((_) => {
1826
- if (_ && _.resolvedModule && _.resolvedModule.packageId && _.resolvedModule.packageId.name === "effect" && !(_.resolvedModule.packageId.version in effectVersions)) {
1827
- effectVersions[_.resolvedModule.packageId.version] = {
1828
- resolvedFileName: _.resolvedModule.resolvedFileName
1829
- };
1830
- }
1831
- });
1832
- }
1833
- effectVersionsCache.set(sourceFile.fileName, effectVersions);
1834
- programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
1835
- }
1836
- if (Object.keys(effectVersions).length > 1) {
1837
- const versions = Object.keys(effectVersions).map((version) => `version ${version}`);
1838
- effectDiagnostics.push({
1839
- node: sourceFile.statements[0],
1840
- category: ts.DiagnosticCategory.Warning,
1841
- messageText: `Seems like in this project there are multiple effect versions loaded (${versions.join(", ")}). This may cause unexpected type errors and runtime behaviours. If you are ok with that, you can disable this warning by adding "multipleEffectCheck": false to the Effect LSP options inside your tsconfig.json`,
1842
- fixes: []
1843
- });
1844
- }
1845
- return effectDiagnostics;
1846
- })
1847
- });
1848
-
1849
2468
  // src/diagnostics/unnecessaryEffectGen.ts
1850
- var unnecessaryEffectGen = createDiagnostic({
1851
- name: "effect/unnecessaryEffectGen",
2469
+ var unnecessaryEffectGen2 = createDiagnostic({
2470
+ name: "unnecessaryEffectGen",
1852
2471
  code: 5,
1853
2472
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile) {
1854
2473
  const ts = yield* service(TypeScriptApi);
@@ -1863,13 +2482,9 @@ var unnecessaryEffectGen = createDiagnostic({
1863
2482
  while (nodeToVisit.length > 0) {
1864
2483
  const node = nodeToVisit.shift();
1865
2484
  ts.forEachChild(node, appendNodeToVisit);
1866
- const maybeNode = yield* pipe(
1867
- effectGen(node),
1868
- flatMap2(({ body }) => returnYieldEffectBlock(body)),
1869
- option
1870
- );
2485
+ const maybeNode = yield* option(unnecessaryEffectGen(node));
1871
2486
  if (isSome2(maybeNode)) {
1872
- unnecessaryGenerators.set(node, maybeNode.value);
2487
+ unnecessaryGenerators.set(node, maybeNode.value.replacementNode);
1873
2488
  }
1874
2489
  }
1875
2490
  unnecessaryGenerators.forEach(
@@ -1884,7 +2499,7 @@ var unnecessaryEffectGen = createDiagnostic({
1884
2499
  const textChanges = yield* service(
1885
2500
  ChangeTracker
1886
2501
  );
1887
- textChanges.replaceNode(sourceFile, effectGenCall, yieldedResult);
2502
+ textChanges.replaceNode(sourceFile, effectGenCall, yield* yieldedResult);
1888
2503
  })
1889
2504
  }]
1890
2505
  })
@@ -1895,12 +2510,12 @@ var unnecessaryEffectGen = createDiagnostic({
1895
2510
 
1896
2511
  // src/diagnostics.ts
1897
2512
  var diagnostics = [
1898
- multipleEffectVersions,
2513
+ duplicatePackage,
1899
2514
  missingEffectContext,
1900
2515
  missingEffectError,
1901
2516
  floatingEffect,
1902
2517
  missingStarInYieldEffectGen,
1903
- unnecessaryEffectGen
2518
+ unnecessaryEffectGen2
1904
2519
  ];
1905
2520
 
1906
2521
  // src/transform.ts
@@ -1916,7 +2531,10 @@ function transform_default(program, pluginConfig, { addDiagnostic, ts: tsInstanc
1916
2531
  TypeCheckerApiCache,
1917
2532
  makeTypeCheckerApiCache()
1918
2533
  ),
1919
- provideService(PluginOptions, parsePluginOptions(pluginConfig)),
2534
+ provideService(
2535
+ LanguageServicePluginOptions,
2536
+ parse(pluginConfig)
2537
+ ),
1920
2538
  run,
1921
2539
  map((_2) => _2.diagnostics),
1922
2540
  map(