@effect/language-service 0.40.0 → 0.41.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/index.js CHANGED
@@ -3499,7 +3499,10 @@ var generate = fn("writeTagClassAccessors.generate")(function* (sourceFile, serv
3499
3499
  ]
3500
3500
  );
3501
3501
  return ts.factory.createPropertyDeclaration(
3502
- [ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)],
3502
+ [
3503
+ ts.factory.createModifier(ts.SyntaxKind.StaticKeyword),
3504
+ ts.factory.createModifier(ts.SyntaxKind.OverrideKeyword)
3505
+ ],
3503
3506
  propertyName,
3504
3507
  void 0,
3505
3508
  type,
@@ -3865,7 +3868,7 @@ var classSelfMismatch = createDiagnostic({
3865
3868
  );
3866
3869
  if (result) {
3867
3870
  const { className, selfTypeNode } = result;
3868
- let actualName = "";
3871
+ let actualName = sourceFile.text.substring(selfTypeNode.pos, selfTypeNode.end);
3869
3872
  if (ts.isTypeReferenceNode(selfTypeNode)) {
3870
3873
  if (ts.isIdentifier(selfTypeNode.typeName)) {
3871
3874
  actualName = ts.idText(selfTypeNode.typeName);
@@ -4582,7 +4585,7 @@ var missingEffectError = createDiagnostic({
4582
4585
  // src/diagnostics/missingEffectServiceDependency.ts
4583
4586
  var missingEffectServiceDependency = createDiagnostic({
4584
4587
  name: "missingEffectServiceDependency",
4585
- code: 21,
4588
+ code: 22,
4586
4589
  severity: "off",
4587
4590
  apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
4588
4591
  const ts = yield* service(TypeScriptApi);
@@ -4904,6 +4907,96 @@ var multipleEffectProvide = createDiagnostic({
4904
4907
  })
4905
4908
  });
4906
4909
 
4910
+ // src/diagnostics/nonObjectEffectServiceType.ts
4911
+ var nonObjectEffectServiceType = createDiagnostic({
4912
+ name: "nonObjectEffectServiceType",
4913
+ code: 24,
4914
+ severity: "error",
4915
+ apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
4916
+ const ts = yield* service(TypeScriptApi);
4917
+ const typeChecker = yield* service(TypeCheckerApi);
4918
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4919
+ const typeParser = yield* service(TypeParser);
4920
+ function isPrimitiveType(type) {
4921
+ return typeCheckerUtils.unrollUnionMembers(type).some(
4922
+ (type2) => !!(type2.flags & ts.TypeFlags.String || type2.flags & ts.TypeFlags.Number || type2.flags & ts.TypeFlags.Boolean || type2.flags & ts.TypeFlags.StringLiteral || type2.flags & ts.TypeFlags.NumberLiteral || type2.flags & ts.TypeFlags.BooleanLiteral || type2.flags & ts.TypeFlags.Undefined || type2.flags & ts.TypeFlags.Null)
4923
+ );
4924
+ }
4925
+ const nodeToVisit = [];
4926
+ const appendNodeToVisit = (node) => {
4927
+ nodeToVisit.push(node);
4928
+ return void 0;
4929
+ };
4930
+ ts.forEachChild(sourceFile, appendNodeToVisit);
4931
+ while (nodeToVisit.length > 0) {
4932
+ const node = nodeToVisit.shift();
4933
+ if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
4934
+ const serviceResult = yield* pipe(
4935
+ typeParser.extendsEffectService(node),
4936
+ orElse2(() => void_)
4937
+ );
4938
+ if (serviceResult && serviceResult.options && ts.isObjectLiteralExpression(serviceResult.options)) {
4939
+ const options = serviceResult.options;
4940
+ for (const property of options.properties) {
4941
+ if (!ts.isPropertyAssignment(property) || !ts.isIdentifier(property.name)) {
4942
+ continue;
4943
+ }
4944
+ const propertyName = ts.idText(property.name);
4945
+ const propertyValue = property.initializer;
4946
+ const errorToReport = {
4947
+ location: property.name,
4948
+ messageText: "Effect.Service requires the service type to be an object {} and not a primitive type. \nConsider wrapping the value in an object, or manually using Context.Tag or Effect.Tag if you want to use a primitive instead.",
4949
+ fixes: []
4950
+ };
4951
+ if (propertyName === "succeed") {
4952
+ const valueType = typeChecker.getTypeAtLocation(propertyValue);
4953
+ if (isPrimitiveType(valueType)) {
4954
+ report(errorToReport);
4955
+ }
4956
+ } else if (propertyName === "sync") {
4957
+ const valueType = typeChecker.getTypeAtLocation(propertyValue);
4958
+ const signatures = typeChecker.getSignaturesOfType(valueType, ts.SignatureKind.Call);
4959
+ for (const signature of signatures) {
4960
+ const returnType = typeChecker.getReturnTypeOfSignature(signature);
4961
+ if (isPrimitiveType(returnType)) {
4962
+ report(errorToReport);
4963
+ break;
4964
+ }
4965
+ }
4966
+ } else if (propertyName === "effect" || propertyName === "scoped") {
4967
+ const valueType = typeChecker.getTypeAtLocation(propertyValue);
4968
+ const effectResult = yield* pipe(
4969
+ typeParser.effectType(valueType, propertyValue),
4970
+ orElse2(() => void_)
4971
+ );
4972
+ if (effectResult) {
4973
+ if (isPrimitiveType(effectResult.A)) {
4974
+ report(errorToReport);
4975
+ continue;
4976
+ }
4977
+ } else {
4978
+ const signatures = typeChecker.getSignaturesOfType(valueType, ts.SignatureKind.Call);
4979
+ for (const signature of signatures) {
4980
+ const returnType = typeChecker.getReturnTypeOfSignature(signature);
4981
+ const effectReturnResult = yield* pipe(
4982
+ typeParser.effectType(returnType, propertyValue),
4983
+ orElse2(() => void_)
4984
+ );
4985
+ if (effectReturnResult && isPrimitiveType(effectReturnResult.A)) {
4986
+ report(errorToReport);
4987
+ break;
4988
+ }
4989
+ }
4990
+ }
4991
+ }
4992
+ }
4993
+ }
4994
+ }
4995
+ ts.forEachChild(node, appendNodeToVisit);
4996
+ }
4997
+ })
4998
+ });
4999
+
4907
5000
  // src/diagnostics/outdatedEffectCodegen.ts
4908
5001
  var outdatedEffectCodegen = createDiagnostic({
4909
5002
  name: "outdatedEffectCodegen",
@@ -5524,7 +5617,8 @@ var diagnostics = [
5524
5617
  multipleEffectProvide,
5525
5618
  outdatedEffectCodegen,
5526
5619
  overriddenSchemaConstructor,
5527
- unsupportedServiceAccessors
5620
+ unsupportedServiceAccessors,
5621
+ nonObjectEffectServiceType
5528
5622
  ];
5529
5623
 
5530
5624
  // src/completions/effectDiagnosticsComment.ts
@@ -13694,45 +13788,56 @@ var init = (modules) => {
13694
13788
  }
13695
13789
  return applicableRenameInfo;
13696
13790
  };
13697
- info.session?.addProtocolHandler("_effectGetLayerMermaid", (arg) => {
13698
- const { character, line, path } = arg.arguments;
13699
- const normalizedPath = modules.typescript.server.toNormalizedPath(path);
13700
- const projectService = info.project.projectService;
13701
- const scriptInfo = projectService.getScriptInfoForNormalizedPath(normalizedPath);
13702
- if (scriptInfo) {
13703
- const targetProject = scriptInfo.getDefaultProject();
13704
- if (targetProject) {
13705
- const program = targetProject.getLanguageService().getProgram();
13706
- if (program) {
13707
- const sourceFile = targetProject.getSourceFile(scriptInfo.path);
13708
- if (sourceFile) {
13709
- return pipe(
13710
- effectApiGetLayerGraph(sourceFile, line, character),
13711
- map3((response) => ({
13712
- response: {
13713
- success: true,
13714
- ...response
13715
- }
13716
- })),
13717
- runNano(program),
13718
- getOrElse((e) => ({
13719
- response: {
13720
- success: false,
13721
- error: e.message
13722
- }
13723
- }))
13724
- );
13791
+ const additionalProtocolHandlers = {
13792
+ "_effectGetLayerMermaid": (arg) => {
13793
+ const { character, line, path } = arg.arguments;
13794
+ const normalizedPath = modules.typescript.server.toNormalizedPath(path);
13795
+ const projectService = info.project.projectService;
13796
+ const scriptInfo = projectService.getScriptInfoForNormalizedPath(normalizedPath);
13797
+ if (scriptInfo) {
13798
+ const targetProject = scriptInfo.getDefaultProject();
13799
+ if (targetProject) {
13800
+ const program = targetProject.getLanguageService().getProgram();
13801
+ if (program) {
13802
+ const sourceFile = targetProject.getSourceFile(scriptInfo.path);
13803
+ if (sourceFile) {
13804
+ return pipe(
13805
+ effectApiGetLayerGraph(sourceFile, line, character),
13806
+ map3((response) => ({
13807
+ response: {
13808
+ success: true,
13809
+ ...response
13810
+ }
13811
+ })),
13812
+ runNano(program),
13813
+ getOrElse((e) => ({
13814
+ response: {
13815
+ success: false,
13816
+ error: e.message
13817
+ }
13818
+ }))
13819
+ );
13820
+ }
13725
13821
  }
13726
13822
  }
13727
13823
  }
13824
+ return {
13825
+ response: {
13826
+ success: false,
13827
+ error: "No source file found"
13828
+ }
13829
+ };
13728
13830
  }
13729
- return {
13730
- response: {
13731
- success: false,
13732
- error: "No source file found"
13831
+ };
13832
+ if (info.session) {
13833
+ for (const [key, value] of Object.entries(additionalProtocolHandlers)) {
13834
+ try {
13835
+ info.session.addProtocolHandler(key, value);
13836
+ } catch (e) {
13837
+ info.project.log("[@effect/language-service] Skipped adding " + key + " protocol handler due to error: " + e);
13733
13838
  }
13734
- };
13735
- });
13839
+ }
13840
+ }
13736
13841
  return proxy;
13737
13842
  }
13738
13843
  return { create, onConfigurationChanged };