@fairfox/polly 0.3.0 → 0.3.2

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.
@@ -727,10 +727,12 @@ import { Project, SyntaxKind, Node } from "ts-morph";
727
727
 
728
728
  class HandlerExtractor {
729
729
  project;
730
+ typeGuardCache;
730
731
  constructor(tsConfigPath) {
731
732
  this.project = new Project({
732
733
  tsConfigFilePath: tsConfigPath
733
734
  });
735
+ this.typeGuardCache = new WeakMap;
734
736
  }
735
737
  extractHandlers() {
736
738
  const handlers = [];
@@ -773,6 +775,10 @@ class HandlerExtractor {
773
775
  const mapHandlers = this.extractHandlerMapPattern(node, context, filePath);
774
776
  handlers.push(...mapHandlers);
775
777
  }
778
+ if (Node.isIfStatement(node)) {
779
+ const typeGuardHandlers = this.extractTypeGuardHandlers(node, context, filePath);
780
+ handlers.push(...typeGuardHandlers);
781
+ }
776
782
  });
777
783
  return handlers;
778
784
  }
@@ -983,6 +989,145 @@ class HandlerExtractor {
983
989
  } catch (error) {}
984
990
  return handlers;
985
991
  }
992
+ extractTypeGuardHandlers(ifNode, context, filePath) {
993
+ const handlers = [];
994
+ try {
995
+ const sourceFile = ifNode.getSourceFile();
996
+ let typeGuards = this.typeGuardCache.get(sourceFile);
997
+ if (!typeGuards) {
998
+ typeGuards = this.findTypePredicateFunctions(sourceFile);
999
+ this.typeGuardCache.set(sourceFile, typeGuards);
1000
+ }
1001
+ if (typeGuards.size === 0) {
1002
+ return handlers;
1003
+ }
1004
+ let currentIf = ifNode;
1005
+ while (currentIf) {
1006
+ const handler = this.extractHandlerFromIfClause(currentIf, typeGuards, context, filePath);
1007
+ if (handler) {
1008
+ handlers.push(handler);
1009
+ }
1010
+ const elseStatement = currentIf.getElseStatement();
1011
+ if (elseStatement && Node.isIfStatement(elseStatement)) {
1012
+ currentIf = elseStatement;
1013
+ } else {
1014
+ break;
1015
+ }
1016
+ }
1017
+ } catch (error) {}
1018
+ return handlers;
1019
+ }
1020
+ extractHandlerFromIfClause(ifNode, typeGuards, context, filePath) {
1021
+ try {
1022
+ const condition = ifNode.getExpression();
1023
+ if (!Node.isCallExpression(condition)) {
1024
+ return null;
1025
+ }
1026
+ const funcExpr = condition.getExpression();
1027
+ let funcName;
1028
+ if (Node.isIdentifier(funcExpr)) {
1029
+ funcName = funcExpr.getText();
1030
+ }
1031
+ let messageType = undefined;
1032
+ if (funcName && typeGuards.has(funcName)) {
1033
+ messageType = typeGuards.get(funcName);
1034
+ } else if (Node.isIdentifier(funcExpr)) {
1035
+ messageType = this.resolveImportedTypeGuard(funcExpr);
1036
+ }
1037
+ if (!messageType) {
1038
+ return null;
1039
+ }
1040
+ const line = ifNode.getStartLineNumber();
1041
+ return {
1042
+ messageType,
1043
+ node: context,
1044
+ assignments: [],
1045
+ preconditions: [],
1046
+ postconditions: [],
1047
+ location: { file: filePath, line }
1048
+ };
1049
+ } catch (error) {
1050
+ return null;
1051
+ }
1052
+ }
1053
+ findTypePredicateFunctions(sourceFile) {
1054
+ const typeGuards = new Map;
1055
+ sourceFile.forEachDescendant((node) => {
1056
+ if (Node.isFunctionDeclaration(node) || Node.isFunctionExpression(node) || Node.isArrowFunction(node)) {
1057
+ const returnType = node.getReturnType();
1058
+ const returnTypeText = returnType.getText();
1059
+ if (/is\s+\w+/.test(returnTypeText)) {
1060
+ let functionName;
1061
+ if (Node.isFunctionDeclaration(node)) {
1062
+ functionName = node.getName();
1063
+ } else if (Node.isFunctionExpression(node)) {
1064
+ const parent = node.getParent();
1065
+ if (Node.isVariableDeclaration(parent)) {
1066
+ functionName = parent.getName();
1067
+ }
1068
+ } else if (Node.isArrowFunction(node)) {
1069
+ const parent = node.getParent();
1070
+ if (Node.isVariableDeclaration(parent)) {
1071
+ functionName = parent.getName();
1072
+ }
1073
+ }
1074
+ if (functionName) {
1075
+ let messageType = null;
1076
+ const typeMatch = returnTypeText.match(/is\s+(\w+)/);
1077
+ if (typeMatch) {
1078
+ const typeName = typeMatch[1];
1079
+ messageType = this.extractMessageTypeFromTypeName(typeName);
1080
+ }
1081
+ if (!messageType) {
1082
+ const body = node.getBody();
1083
+ if (body) {
1084
+ const bodyText = body.getText();
1085
+ const typeValueMatch = bodyText.match(/\.type\s*===?\s*['"](\w+)['"]/);
1086
+ if (typeValueMatch) {
1087
+ messageType = typeValueMatch[1];
1088
+ }
1089
+ }
1090
+ }
1091
+ if (messageType) {
1092
+ typeGuards.set(functionName, messageType);
1093
+ }
1094
+ }
1095
+ }
1096
+ }
1097
+ });
1098
+ return typeGuards;
1099
+ }
1100
+ resolveImportedTypeGuard(identifier) {
1101
+ try {
1102
+ const definitions = identifier.getDefinitionNodes();
1103
+ for (const def of definitions) {
1104
+ if (Node.isFunctionDeclaration(def) || Node.isFunctionExpression(def) || Node.isArrowFunction(def)) {
1105
+ const returnType = def.getReturnType();
1106
+ const returnTypeText = returnType.getText();
1107
+ if (/is\s+\w+/.test(returnTypeText)) {
1108
+ const typeMatch = returnTypeText.match(/is\s+(\w+)/);
1109
+ if (typeMatch) {
1110
+ const typeName = typeMatch[1];
1111
+ return this.extractMessageTypeFromTypeName(typeName);
1112
+ }
1113
+ const body = def.getBody();
1114
+ if (body) {
1115
+ const bodyText = body.getText();
1116
+ const typeValueMatch = bodyText.match(/\.type\s*===?\s*['"](\w+)['"]/);
1117
+ if (typeValueMatch) {
1118
+ return typeValueMatch[1];
1119
+ }
1120
+ }
1121
+ }
1122
+ }
1123
+ }
1124
+ } catch (error) {}
1125
+ return null;
1126
+ }
1127
+ extractMessageTypeFromTypeName(typeName) {
1128
+ const messageType = typeName.replace(/Message$/, "").replace(/Event$/, "").replace(/Request$/, "").replace(/Command$/, "").replace(/Query$/, "").toLowerCase();
1129
+ return messageType;
1130
+ }
986
1131
  inferContext(filePath) {
987
1132
  const path = filePath.toLowerCase();
988
1133
  if (path.includes("/background/") || path.includes("\\background\\")) {
@@ -2175,4 +2320,4 @@ Stack trace:`, COLORS.gray));
2175
2320
  process.exit(1);
2176
2321
  });
2177
2322
 
2178
- //# debugId=8C53367A419D15AA64756E2164756E21
2323
+ //# debugId=45501E6F6BA7319064756E2164756E21