{"version":3,"sources":["../../src/failures/getExpectTypeFailures.ts"],"sourcesContent":["import type ts from \"typescript\";\n\nimport { Assertions } from \"../assertions/types.js\";\nimport { getNodeAtPosition, lineOfPosition } from \"../utils/locations.js\";\nimport {\n\tgetLanguageServiceHost,\n\tgetNodeForExpectType,\n\tmatchModuloWhitespace,\n} from \"../utils/typescript.js\";\nimport { ResolvedVersionToTest } from \"../utils/versions.js\";\nimport { normalizedTypeToString } from \"./normalizedTypeToString.js\";\nimport { ExpectTypeFailures, UnmetExpectation } from \"./types.js\";\n\nexport function getExpectTypeFailures(\n\tassertions: Pick<Assertions, \"twoSlashAssertions\" | \"typeAssertions\">,\n\t{ program, sourceFile, tsModule, version }: ResolvedVersionToTest,\n): ExpectTypeFailures {\n\tconst checker = program.getTypeChecker();\n\tconst languageService = tsModule.createLanguageService(\n\t\tgetLanguageServiceHost(program, tsModule),\n\t);\n\tconst { twoSlashAssertions, typeAssertions } = assertions;\n\tconst unmetExpectations: UnmetExpectation[] = [];\n\n\t// Match assertions to the first node that appears on the line they apply to.\n\ttsModule.forEachChild(sourceFile, function iterate(node) {\n\t\tconst line = lineOfPosition(node.getStart(sourceFile), sourceFile);\n\t\tconst assertion = typeAssertions.get(line);\n\t\tif (assertion !== undefined) {\n\t\t\tconst { expected } = assertion;\n\n\t\t\tlet nodeToCheck = node;\n\n\t\t\t// https://github.com/Microsoft/TypeScript/issues/14077\n\t\t\tif (node.kind === tsModule.SyntaxKind.ExpressionStatement) {\n\t\t\t\tnode = (node as ts.ExpressionStatement).expression;\n\t\t\t}\n\n\t\t\tnodeToCheck = getNodeForExpectType(node, tsModule);\n\t\t\tconst type = checker.getTypeAtLocation(nodeToCheck);\n\t\t\tconst actual = checker.typeToString(\n\t\t\t\ttype,\n\t\t\t\t/*enclosingDeclaration*/ undefined,\n\t\t\t\ttsModule.TypeFormatFlags.NoTruncation,\n\t\t\t);\n\n\t\t\ttypeAssertions.delete(line);\n\n\t\t\tconst candidates = expected\n\t\t\t\t?.split(/\\s*\\|\\|\\s*/)\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter(Boolean);\n\n\t\t\tif (!candidates || !candidateTypeMatches(actual, candidates)) {\n\t\t\t\tunmetExpectations.push({ actual, assertion, node, version });\n\t\t\t}\n\t\t}\n\n\t\ttsModule.forEachChild(node, iterate);\n\t});\n\n\tfunction candidateTypeMatches(actual: string, candidates: string[]) {\n\t\tlet actualNormalized: string | undefined;\n\n\t\tfor (const candidate of candidates) {\n\t\t\tif (candidate === actual) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tactualNormalized ??= normalizedTypeToString(actual, tsModule);\n\t\t\tconst candidateNormalized = normalizedTypeToString(candidate, tsModule);\n\n\t\t\tif (actualNormalized === candidateNormalized) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tconst twoSlashFailureLines: number[] = [];\n\tif (twoSlashAssertions.length) {\n\t\tfor (const assertion of twoSlashAssertions) {\n\t\t\tconst { expected, position } = assertion;\n\t\t\tif (position === -1) {\n\t\t\t\t// special case for a twoslash assertion on line 1.\n\t\t\t\ttwoSlashFailureLines.push(0);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst node = getNodeAtPosition(sourceFile, position, tsModule);\n\t\t\tif (!node) {\n\t\t\t\ttwoSlashFailureLines.push(\n\t\t\t\t\tsourceFile.getLineAndCharacterOfPosition(position).line,\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst qi = languageService.getQuickInfoAtPosition(\n\t\t\t\tsourceFile.fileName,\n\t\t\t\tnode.getStart(),\n\t\t\t);\n\t\t\tif (!qi?.displayParts) {\n\t\t\t\ttwoSlashFailureLines.push(\n\t\t\t\t\tsourceFile.getLineAndCharacterOfPosition(position).line,\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst actual = qi.displayParts.map((dp) => dp.text).join(\"\");\n\t\t\tif (!matchModuloWhitespace(actual, expected)) {\n\t\t\t\tunmetExpectations.push({\n\t\t\t\t\tactual,\n\t\t\t\t\tassertion,\n\t\t\t\t\tnode,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tunmetExpectations,\n\t\tunusedAssertions: [...twoSlashFailureLines, ...typeAssertions.keys()],\n\t};\n}\n"],"mappings":";AAGA,SAAS,mBAAmB,sBAAsB;AAClD;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAEP,SAAS,8BAA8B;AAGhC,SAAS,sBACf,YACA,EAAE,SAAS,YAAY,UAAU,QAAQ,GACpB;AACrB,QAAM,UAAU,QAAQ,eAAe;AACvC,QAAM,kBAAkB,SAAS;AAAA,IAChC,uBAAuB,SAAS,QAAQ;AAAA,EACzC;AACA,QAAM,EAAE,oBAAoB,eAAe,IAAI;AAC/C,QAAM,oBAAwC,CAAC;AAG/C,WAAS,aAAa,YAAY,SAAS,QAAQ,MAAM;AACxD,UAAM,OAAO,eAAe,KAAK,SAAS,UAAU,GAAG,UAAU;AACjE,UAAM,YAAY,eAAe,IAAI,IAAI;AACzC,QAAI,cAAc,QAAW;AAC5B,YAAM,EAAE,SAAS,IAAI;AAErB,UAAI,cAAc;AAGlB,UAAI,KAAK,SAAS,SAAS,WAAW,qBAAqB;AAC1D,eAAQ,KAAgC;AAAA,MACzC;AAEA,oBAAc,qBAAqB,MAAM,QAAQ;AACjD,YAAM,OAAO,QAAQ,kBAAkB,WAAW;AAClD,YAAM,SAAS,QAAQ;AAAA,QACtB;AAAA;AAAA,QACyB;AAAA,QACzB,SAAS,gBAAgB;AAAA,MAC1B;AAEA,qBAAe,OAAO,IAAI;AAE1B,YAAM,aAAa,UAChB,MAAM,YAAY,EACnB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AAEhB,UAAI,CAAC,cAAc,CAAC,qBAAqB,QAAQ,UAAU,GAAG;AAC7D,0BAAkB,KAAK,EAAE,QAAQ,WAAW,MAAM,QAAQ,CAAC;AAAA,MAC5D;AAAA,IACD;AAEA,aAAS,aAAa,MAAM,OAAO;AAAA,EACpC,CAAC;AAED,WAAS,qBAAqB,QAAgB,YAAsB;AACnE,QAAI;AAEJ,eAAW,aAAa,YAAY;AACnC,UAAI,cAAc,QAAQ;AACzB,eAAO;AAAA,MACR;AAEA,2BAAqB,uBAAuB,QAAQ,QAAQ;AAC5D,YAAM,sBAAsB,uBAAuB,WAAW,QAAQ;AAEtE,UAAI,qBAAqB,qBAAqB;AAC7C,eAAO;AAAA,MACR;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAEA,QAAM,uBAAiC,CAAC;AACxC,MAAI,mBAAmB,QAAQ;AAC9B,eAAW,aAAa,oBAAoB;AAC3C,YAAM,EAAE,UAAU,SAAS,IAAI;AAC/B,UAAI,aAAa,IAAI;AAEpB,6BAAqB,KAAK,CAAC;AAC3B;AAAA,MACD;AAEA,YAAM,OAAO,kBAAkB,YAAY,UAAU,QAAQ;AAC7D,UAAI,CAAC,MAAM;AACV,6BAAqB;AAAA,UACpB,WAAW,8BAA8B,QAAQ,EAAE;AAAA,QACpD;AACA;AAAA,MACD;AAEA,YAAM,KAAK,gBAAgB;AAAA,QAC1B,WAAW;AAAA,QACX,KAAK,SAAS;AAAA,MACf;AACA,UAAI,CAAC,IAAI,cAAc;AACtB,6BAAqB;AAAA,UACpB,WAAW,8BAA8B,QAAQ,EAAE;AAAA,QACpD;AACA;AAAA,MACD;AAEA,YAAM,SAAS,GAAG,aAAa,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,KAAK,EAAE;AAC3D,UAAI,CAAC,sBAAsB,QAAQ,QAAQ,GAAG;AAC7C,0BAAkB,KAAK;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AAAA,IACN;AAAA,IACA,kBAAkB,CAAC,GAAG,sBAAsB,GAAG,eAAe,KAAK,CAAC;AAAA,EACrE;AACD;","names":[]}