@formspec/build 0.1.0-alpha.57 → 0.1.0-alpha.59
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/dist/analyzer/builtin-brands.d.ts +10 -7
- package/dist/analyzer/builtin-brands.d.ts.map +1 -1
- package/dist/analyzer/class-analyzer.d.ts +29 -0
- package/dist/analyzer/class-analyzer.d.ts.map +1 -1
- package/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
- package/dist/browser.cjs +126 -31
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +129 -32
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +431 -12
- package/dist/build-beta.d.ts +399 -12
- package/dist/build-internal.d.ts +460 -12
- package/dist/build.d.ts +399 -12
- package/dist/cli.cjs +625 -326
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +586 -279
- package/dist/cli.js.map +1 -1
- package/dist/extensions/registry.d.ts +19 -1
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/extensions/resolve-custom-type.d.ts.map +1 -1
- package/dist/extensions/ts-type-utils.d.ts +0 -11
- package/dist/extensions/ts-type-utils.d.ts.map +1 -1
- package/dist/generators/class-schema.d.ts.map +1 -1
- package/dist/index.cjs +615 -315
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +585 -277
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +589 -289
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +554 -246
- package/dist/internals.js.map +1 -1
- package/package.json +5 -5
package/dist/internals.js
CHANGED
|
@@ -791,21 +791,21 @@ function wrapInConditional(field, layout, provenance) {
|
|
|
791
791
|
}
|
|
792
792
|
|
|
793
793
|
// src/analyzer/program.ts
|
|
794
|
-
import * as
|
|
794
|
+
import * as ts6 from "typescript";
|
|
795
795
|
import * as path from "path";
|
|
796
796
|
|
|
797
797
|
// src/analyzer/class-analyzer.ts
|
|
798
|
-
import * as
|
|
798
|
+
import * as ts5 from "typescript";
|
|
799
799
|
import {
|
|
800
800
|
analyzeMetadataForNodeWithChecker,
|
|
801
801
|
parseCommentBlock
|
|
802
802
|
} from "@formspec/analysis/internal";
|
|
803
803
|
|
|
804
804
|
// src/analyzer/jsdoc-constraints.ts
|
|
805
|
-
import * as
|
|
805
|
+
import * as ts4 from "typescript";
|
|
806
806
|
|
|
807
807
|
// src/analyzer/tsdoc-parser.ts
|
|
808
|
-
import * as
|
|
808
|
+
import * as ts3 from "typescript";
|
|
809
809
|
import {
|
|
810
810
|
checkSyntheticTagApplication,
|
|
811
811
|
choosePreferredPayloadText,
|
|
@@ -832,25 +832,10 @@ import { noopLogger } from "@formspec/core";
|
|
|
832
832
|
|
|
833
833
|
// src/extensions/resolve-custom-type.ts
|
|
834
834
|
import * as ts2 from "typescript";
|
|
835
|
-
import { stripNullishUnion } from "@formspec/analysis/internal";
|
|
835
|
+
import { _collectBrandIdentifiers, stripNullishUnion } from "@formspec/analysis/internal";
|
|
836
836
|
|
|
837
837
|
// src/extensions/ts-type-utils.ts
|
|
838
838
|
import * as ts from "typescript";
|
|
839
|
-
function collectBrandIdentifiers(type) {
|
|
840
|
-
if (!type.isIntersection()) {
|
|
841
|
-
return [];
|
|
842
|
-
}
|
|
843
|
-
const brands = [];
|
|
844
|
-
for (const prop of type.getProperties()) {
|
|
845
|
-
const decl = prop.valueDeclaration ?? prop.declarations?.[0];
|
|
846
|
-
if (decl === void 0) continue;
|
|
847
|
-
if (!ts.isPropertySignature(decl) && !ts.isPropertyDeclaration(decl)) continue;
|
|
848
|
-
if (!ts.isComputedPropertyName(decl.name)) continue;
|
|
849
|
-
if (!ts.isIdentifier(decl.name.expression)) continue;
|
|
850
|
-
brands.push(decl.name.expression.text);
|
|
851
|
-
}
|
|
852
|
-
return brands;
|
|
853
|
-
}
|
|
854
839
|
function resolveCanonicalSymbol(type, checker) {
|
|
855
840
|
const raw = type.aliasSymbol ?? type.getSymbol();
|
|
856
841
|
if (raw === void 0) return void 0;
|
|
@@ -935,7 +920,7 @@ function resolveCustomTypeFromTsType(type, checker, registry, sourceNode) {
|
|
|
935
920
|
return bySymbol;
|
|
936
921
|
}
|
|
937
922
|
}
|
|
938
|
-
for (const brand of
|
|
923
|
+
for (const brand of _collectBrandIdentifiers(stripped)) {
|
|
939
924
|
const byBrand = registry.findTypeByBrand(brand);
|
|
940
925
|
if (byBrand !== void 0) {
|
|
941
926
|
return byBrand;
|
|
@@ -948,18 +933,19 @@ function customTypeIdFromLookup(result) {
|
|
|
948
933
|
}
|
|
949
934
|
|
|
950
935
|
// src/analyzer/builtin-brands.ts
|
|
951
|
-
import
|
|
952
|
-
function isIntegerBrandedType(type) {
|
|
953
|
-
if (!type.isIntersection()) return false;
|
|
954
|
-
if (!type.types.some((member) => !!(member.flags & ts3.TypeFlags.Number))) return false;
|
|
955
|
-
return collectBrandIdentifiers(type).includes("__integerBrand");
|
|
956
|
-
}
|
|
936
|
+
import { _isIntegerBrandedType } from "@formspec/analysis/internal";
|
|
957
937
|
|
|
958
938
|
// src/analyzer/tsdoc-parser.ts
|
|
959
939
|
import {
|
|
940
|
+
_emitSetupDiagnostics,
|
|
941
|
+
_mapSetupDiagnosticCode,
|
|
960
942
|
getBuildLogger,
|
|
961
943
|
getBroadeningLogger,
|
|
962
944
|
getSyntheticLogger,
|
|
945
|
+
getTypedParserLogger,
|
|
946
|
+
extractEffectiveArgumentText,
|
|
947
|
+
mapTypedParserDiagnosticCode,
|
|
948
|
+
parseTagArgument,
|
|
963
949
|
describeTypeKind,
|
|
964
950
|
elapsedMicros,
|
|
965
951
|
nowMicros,
|
|
@@ -971,7 +957,7 @@ function sharedTagValueOptions(options) {
|
|
|
971
957
|
...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {}
|
|
972
958
|
};
|
|
973
959
|
}
|
|
974
|
-
var SYNTHETIC_TYPE_FORMAT_FLAGS =
|
|
960
|
+
var SYNTHETIC_TYPE_FORMAT_FLAGS = ts3.TypeFormatFlags.NoTruncation | ts3.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
975
961
|
function getExtensionTypeNames(registry) {
|
|
976
962
|
if (registry === void 0) {
|
|
977
963
|
return /* @__PURE__ */ new Set();
|
|
@@ -985,23 +971,23 @@ function getExtensionTypeNames(registry) {
|
|
|
985
971
|
function collectImportedNames(sourceFile) {
|
|
986
972
|
const importedNames = /* @__PURE__ */ new Set();
|
|
987
973
|
for (const statement of sourceFile.statements) {
|
|
988
|
-
if (
|
|
974
|
+
if (ts3.isImportDeclaration(statement) && statement.importClause !== void 0) {
|
|
989
975
|
const clause = statement.importClause;
|
|
990
976
|
if (clause.name !== void 0) {
|
|
991
977
|
importedNames.add(clause.name.text);
|
|
992
978
|
}
|
|
993
979
|
if (clause.namedBindings !== void 0) {
|
|
994
|
-
if (
|
|
980
|
+
if (ts3.isNamedImports(clause.namedBindings)) {
|
|
995
981
|
for (const specifier of clause.namedBindings.elements) {
|
|
996
982
|
importedNames.add(specifier.name.text);
|
|
997
983
|
}
|
|
998
|
-
} else if (
|
|
984
|
+
} else if (ts3.isNamespaceImport(clause.namedBindings)) {
|
|
999
985
|
importedNames.add(clause.namedBindings.name.text);
|
|
1000
986
|
}
|
|
1001
987
|
}
|
|
1002
988
|
continue;
|
|
1003
989
|
}
|
|
1004
|
-
if (
|
|
990
|
+
if (ts3.isImportEqualsDeclaration(statement)) {
|
|
1005
991
|
importedNames.add(statement.name.text);
|
|
1006
992
|
}
|
|
1007
993
|
}
|
|
@@ -1009,13 +995,13 @@ function collectImportedNames(sourceFile) {
|
|
|
1009
995
|
}
|
|
1010
996
|
function isNonReferenceIdentifier(node) {
|
|
1011
997
|
const parent = node.parent;
|
|
1012
|
-
if ((
|
|
998
|
+
if ((ts3.isBindingElement(parent) || ts3.isClassDeclaration(parent) || ts3.isEnumDeclaration(parent) || ts3.isEnumMember(parent) || ts3.isFunctionDeclaration(parent) || ts3.isFunctionExpression(parent) || ts3.isImportClause(parent) || ts3.isImportEqualsDeclaration(parent) || ts3.isImportSpecifier(parent) || ts3.isInterfaceDeclaration(parent) || ts3.isMethodDeclaration(parent) || ts3.isMethodSignature(parent) || ts3.isModuleDeclaration(parent) || ts3.isNamespaceExport(parent) || ts3.isNamespaceImport(parent) || ts3.isParameter(parent) || ts3.isPropertyDeclaration(parent) || ts3.isPropertySignature(parent) || ts3.isSetAccessorDeclaration(parent) || ts3.isGetAccessorDeclaration(parent) || ts3.isTypeAliasDeclaration(parent) || ts3.isTypeParameterDeclaration(parent) || ts3.isVariableDeclaration(parent)) && parent.name === node) {
|
|
1013
999
|
return true;
|
|
1014
1000
|
}
|
|
1015
|
-
if ((
|
|
1001
|
+
if ((ts3.isPropertyAssignment(parent) || ts3.isPropertyAccessExpression(parent)) && parent.name === node) {
|
|
1016
1002
|
return true;
|
|
1017
1003
|
}
|
|
1018
|
-
if (
|
|
1004
|
+
if (ts3.isQualifiedName(parent) && parent.right === node) {
|
|
1019
1005
|
return true;
|
|
1020
1006
|
}
|
|
1021
1007
|
return false;
|
|
@@ -1027,20 +1013,20 @@ function astReferencesImportedName(root, importedNames) {
|
|
|
1027
1013
|
let found = false;
|
|
1028
1014
|
const visit = (node) => {
|
|
1029
1015
|
if (found) return;
|
|
1030
|
-
if (
|
|
1016
|
+
if (ts3.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
|
|
1031
1017
|
found = true;
|
|
1032
1018
|
return;
|
|
1033
1019
|
}
|
|
1034
|
-
|
|
1020
|
+
ts3.forEachChild(node, visit);
|
|
1035
1021
|
};
|
|
1036
1022
|
visit(root);
|
|
1037
1023
|
return found;
|
|
1038
1024
|
}
|
|
1039
1025
|
function getObjectMembers(statement) {
|
|
1040
|
-
if (
|
|
1026
|
+
if (ts3.isInterfaceDeclaration(statement)) {
|
|
1041
1027
|
return statement.members;
|
|
1042
1028
|
}
|
|
1043
|
-
if (
|
|
1029
|
+
if (ts3.isTypeLiteralNode(statement.type)) {
|
|
1044
1030
|
return statement.type.members;
|
|
1045
1031
|
}
|
|
1046
1032
|
return void 0;
|
|
@@ -1052,7 +1038,7 @@ function rewriteImportedMemberTypes(statement, sourceFile, importedNames) {
|
|
|
1052
1038
|
}
|
|
1053
1039
|
const replacements = [];
|
|
1054
1040
|
for (const member of members) {
|
|
1055
|
-
if (!
|
|
1041
|
+
if (!ts3.isPropertySignature(member)) {
|
|
1056
1042
|
if (astReferencesImportedName(member, importedNames)) {
|
|
1057
1043
|
return null;
|
|
1058
1044
|
}
|
|
@@ -1084,14 +1070,14 @@ function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
|
|
|
1084
1070
|
);
|
|
1085
1071
|
const result = [];
|
|
1086
1072
|
for (const statement of sourceFile.statements) {
|
|
1087
|
-
if (
|
|
1088
|
-
if (
|
|
1089
|
-
if (
|
|
1073
|
+
if (ts3.isImportDeclaration(statement)) continue;
|
|
1074
|
+
if (ts3.isImportEqualsDeclaration(statement)) continue;
|
|
1075
|
+
if (ts3.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0) continue;
|
|
1090
1076
|
if (!astReferencesImportedName(statement, importedNamesToSkip)) {
|
|
1091
1077
|
result.push(statement.getText(sourceFile));
|
|
1092
1078
|
continue;
|
|
1093
1079
|
}
|
|
1094
|
-
if (
|
|
1080
|
+
if (ts3.isInterfaceDeclaration(statement) || ts3.isTypeAliasDeclaration(statement)) {
|
|
1095
1081
|
const rewritten = rewriteImportedMemberTypes(statement, sourceFile, importedNamesToSkip);
|
|
1096
1082
|
if (rewritten !== null) {
|
|
1097
1083
|
result.push(rewritten);
|
|
@@ -1116,6 +1102,7 @@ function processConstraintTag(tagName, text, parsedTag, provenance, node, source
|
|
|
1116
1102
|
sourceFile,
|
|
1117
1103
|
tagName,
|
|
1118
1104
|
parsedTag,
|
|
1105
|
+
text,
|
|
1119
1106
|
provenance,
|
|
1120
1107
|
supportingDeclarations,
|
|
1121
1108
|
options
|
|
@@ -1143,6 +1130,9 @@ function renderSyntheticArgumentExpression(valueKind, argumentText) {
|
|
|
1143
1130
|
case "number":
|
|
1144
1131
|
case "integer":
|
|
1145
1132
|
case "signedInteger":
|
|
1133
|
+
if (trimmed === "Infinity" || trimmed === "-Infinity" || trimmed === "NaN") {
|
|
1134
|
+
return trimmed;
|
|
1135
|
+
}
|
|
1146
1136
|
return Number.isFinite(Number(trimmed)) ? trimmed : JSON.stringify(trimmed);
|
|
1147
1137
|
case "string":
|
|
1148
1138
|
return JSON.stringify(argumentText);
|
|
@@ -1190,7 +1180,7 @@ function stripHintNullishUnion(type) {
|
|
|
1190
1180
|
return type;
|
|
1191
1181
|
}
|
|
1192
1182
|
const nonNullish = type.types.filter(
|
|
1193
|
-
(member) => (member.flags & (
|
|
1183
|
+
(member) => (member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined)) === 0
|
|
1194
1184
|
);
|
|
1195
1185
|
if (nonNullish.length === 1 && nonNullish[0] !== void 0) {
|
|
1196
1186
|
return nonNullish[0];
|
|
@@ -1206,10 +1196,10 @@ function isUserEmittableHintProperty(property, declaration) {
|
|
|
1206
1196
|
}
|
|
1207
1197
|
if ("name" in declaration && declaration.name !== void 0) {
|
|
1208
1198
|
const name = declaration.name;
|
|
1209
|
-
if (
|
|
1199
|
+
if (ts3.isComputedPropertyName(name) || ts3.isPrivateIdentifier(name)) {
|
|
1210
1200
|
return false;
|
|
1211
1201
|
}
|
|
1212
|
-
if (!
|
|
1202
|
+
if (!ts3.isIdentifier(name) && !ts3.isStringLiteral(name) && !ts3.isNumericLiteral(name)) {
|
|
1213
1203
|
return false;
|
|
1214
1204
|
}
|
|
1215
1205
|
}
|
|
@@ -1354,7 +1344,7 @@ function hasBuiltinConstraintBroadening(tagName, options) {
|
|
|
1354
1344
|
const broadenedTypeId = getBroadenedCustomTypeId(options?.fieldType);
|
|
1355
1345
|
return broadenedTypeId !== void 0 && options?.extensionRegistry?.findBuiltinConstraintBroadening(broadenedTypeId, tagName) !== void 0;
|
|
1356
1346
|
}
|
|
1357
|
-
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, provenance, supportingDeclarations, options) {
|
|
1347
|
+
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance, supportingDeclarations, options) {
|
|
1358
1348
|
if (!isBuiltinConstraintName(tagName)) {
|
|
1359
1349
|
return [];
|
|
1360
1350
|
}
|
|
@@ -1375,8 +1365,10 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
1375
1365
|
const log = getBuildLogger();
|
|
1376
1366
|
const broadeningLog = getBroadeningLogger();
|
|
1377
1367
|
const syntheticLog = getSyntheticLogger();
|
|
1368
|
+
const typedParserLog = getTypedParserLogger();
|
|
1378
1369
|
const logsEnabled = log !== noopLogger || broadeningLog !== noopLogger;
|
|
1379
1370
|
const syntheticTraceEnabled = syntheticLog !== noopLogger;
|
|
1371
|
+
const typedParserTraceEnabled = typedParserLog !== noopLogger;
|
|
1380
1372
|
const logStart = logsEnabled ? nowMicros() : 0;
|
|
1381
1373
|
const subjectTypeKind = logsEnabled ? describeTypeKind(subjectType, checker) : "";
|
|
1382
1374
|
function emit(outcome, result2) {
|
|
@@ -1453,7 +1445,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
1453
1445
|
}
|
|
1454
1446
|
const hasBroadening = (() => {
|
|
1455
1447
|
if (target === null) {
|
|
1456
|
-
if (
|
|
1448
|
+
if (_isIntegerBrandedType(stripNullishUnion2(subjectType)) && definition.capabilities.includes("numeric-comparable")) {
|
|
1457
1449
|
return true;
|
|
1458
1450
|
}
|
|
1459
1451
|
return hasBuiltinConstraintBroadening(tagName, options);
|
|
@@ -1484,16 +1476,41 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
1484
1476
|
]);
|
|
1485
1477
|
}
|
|
1486
1478
|
}
|
|
1487
|
-
const argumentExpression = renderSyntheticArgumentExpression(
|
|
1488
|
-
definition.valueKind,
|
|
1489
|
-
parsedTag?.argumentText ?? ""
|
|
1490
|
-
);
|
|
1491
|
-
if (definition.requiresArgument && argumentExpression === null) {
|
|
1492
|
-
return emit("A-pass", []);
|
|
1493
|
-
}
|
|
1494
1479
|
if (hasBroadening) {
|
|
1495
1480
|
return emit("bypass", []);
|
|
1496
1481
|
}
|
|
1482
|
+
const effectiveArgumentText = extractEffectiveArgumentText(tagName, rawText, parsedTag);
|
|
1483
|
+
const typedParseResult = parseTagArgument(tagName, effectiveArgumentText, "build");
|
|
1484
|
+
if (!typedParseResult.ok) {
|
|
1485
|
+
if (typedParserTraceEnabled) {
|
|
1486
|
+
typedParserLog.trace("typed-parser C-reject", {
|
|
1487
|
+
consumer: "build",
|
|
1488
|
+
tag: tagName,
|
|
1489
|
+
placement: nonNullPlacement,
|
|
1490
|
+
subjectTypeKind: subjectTypeKind !== "" ? subjectTypeKind : "-",
|
|
1491
|
+
roleOutcome: "C-reject",
|
|
1492
|
+
diagnosticCode: typedParseResult.diagnostic.code
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
const mappedCode = mapTypedParserDiagnosticCode(typedParseResult.diagnostic.code, tagName);
|
|
1496
|
+
return emit("C-reject", [
|
|
1497
|
+
makeDiagnostic(mappedCode, typedParseResult.diagnostic.message, provenance)
|
|
1498
|
+
]);
|
|
1499
|
+
}
|
|
1500
|
+
if (typedParserTraceEnabled) {
|
|
1501
|
+
typedParserLog.trace("typed-parser C-pass", {
|
|
1502
|
+
consumer: "build",
|
|
1503
|
+
tag: tagName,
|
|
1504
|
+
placement: nonNullPlacement,
|
|
1505
|
+
subjectTypeKind: subjectTypeKind !== "" ? subjectTypeKind : "-",
|
|
1506
|
+
roleOutcome: "C-pass",
|
|
1507
|
+
valueKind: typedParseResult.value.kind
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
const argumentExpression = renderSyntheticArgumentExpression(
|
|
1511
|
+
definition.valueKind,
|
|
1512
|
+
effectiveArgumentText
|
|
1513
|
+
);
|
|
1497
1514
|
const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
1498
1515
|
const hostType = options?.hostType ?? subjectType;
|
|
1499
1516
|
const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
@@ -1532,13 +1549,13 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
1532
1549
|
} : {}
|
|
1533
1550
|
});
|
|
1534
1551
|
if (result.diagnostics.length === 0) {
|
|
1535
|
-
return emit("
|
|
1552
|
+
return emit("D-pass", []);
|
|
1536
1553
|
}
|
|
1537
1554
|
const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
|
|
1538
1555
|
if (setupDiagnostic !== void 0) {
|
|
1539
1556
|
return emit("C-reject", [
|
|
1540
1557
|
makeDiagnostic(
|
|
1541
|
-
setupDiagnostic.kind
|
|
1558
|
+
_mapSetupDiagnosticCode(setupDiagnostic.kind),
|
|
1542
1559
|
setupDiagnostic.message,
|
|
1543
1560
|
provenance
|
|
1544
1561
|
)
|
|
@@ -1606,6 +1623,16 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
1606
1623
|
if (cached !== void 0) {
|
|
1607
1624
|
return cached;
|
|
1608
1625
|
}
|
|
1626
|
+
const setupDiags = options?.extensionRegistry?.setupDiagnostics;
|
|
1627
|
+
if (setupDiags !== void 0 && setupDiags.length > 0) {
|
|
1628
|
+
const result2 = {
|
|
1629
|
+
constraints: [],
|
|
1630
|
+
annotations: [],
|
|
1631
|
+
diagnostics: _emitSetupDiagnostics(setupDiags, file)
|
|
1632
|
+
};
|
|
1633
|
+
parseResultCache.set(cacheKey, result2);
|
|
1634
|
+
return result2;
|
|
1635
|
+
}
|
|
1609
1636
|
const constraints = [];
|
|
1610
1637
|
const annotations = [];
|
|
1611
1638
|
const diagnostics = [];
|
|
@@ -1617,12 +1644,12 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
1617
1644
|
const sourceText = sourceFile.getFullText();
|
|
1618
1645
|
const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
|
|
1619
1646
|
const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
|
|
1620
|
-
const commentRanges =
|
|
1647
|
+
const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1621
1648
|
const rawTextFallbacks = collectRawTextFallbacks(node, file);
|
|
1622
1649
|
const extensionTagNames = getExtensionTagNames(options);
|
|
1623
1650
|
if (commentRanges) {
|
|
1624
1651
|
for (const range of commentRanges) {
|
|
1625
|
-
if (range.kind !==
|
|
1652
|
+
if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) {
|
|
1626
1653
|
continue;
|
|
1627
1654
|
}
|
|
1628
1655
|
const commentText = sourceText.substring(range.pos, range.end);
|
|
@@ -1779,10 +1806,10 @@ function extractDisplayNameMetadata(node) {
|
|
|
1779
1806
|
const memberDisplayNames = /* @__PURE__ */ new Map();
|
|
1780
1807
|
const sourceFile = node.getSourceFile();
|
|
1781
1808
|
const sourceText = sourceFile.getFullText();
|
|
1782
|
-
const commentRanges =
|
|
1809
|
+
const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1783
1810
|
if (commentRanges) {
|
|
1784
1811
|
for (const range of commentRanges) {
|
|
1785
|
-
if (range.kind !==
|
|
1812
|
+
if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) continue;
|
|
1786
1813
|
const commentText = sourceText.substring(range.pos, range.end);
|
|
1787
1814
|
if (!commentText.startsWith("/**")) continue;
|
|
1788
1815
|
const unified = parseUnifiedComment(commentText);
|
|
@@ -1807,7 +1834,7 @@ function extractDisplayNameMetadata(node) {
|
|
|
1807
1834
|
}
|
|
1808
1835
|
function collectRawTextFallbacks(node, file) {
|
|
1809
1836
|
const fallbacks = /* @__PURE__ */ new Map();
|
|
1810
|
-
for (const tag of
|
|
1837
|
+
for (const tag of ts3.getJSDocTags(node)) {
|
|
1811
1838
|
const tagName = normalizeConstraintTagName(tag.tagName.text);
|
|
1812
1839
|
if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
1813
1840
|
const commentText = getTagCommentText(tag)?.trim() ?? "";
|
|
@@ -1862,7 +1889,7 @@ function getTagCommentText(tag) {
|
|
|
1862
1889
|
if (typeof tag.comment === "string") {
|
|
1863
1890
|
return tag.comment;
|
|
1864
1891
|
}
|
|
1865
|
-
return
|
|
1892
|
+
return ts3.getTextOfJSDocComment(tag.comment);
|
|
1866
1893
|
}
|
|
1867
1894
|
|
|
1868
1895
|
// src/analyzer/jsdoc-constraints.ts
|
|
@@ -1880,18 +1907,18 @@ function extractJSDocAnnotationNodes(node, file = "", options) {
|
|
|
1880
1907
|
function extractDefaultValueAnnotation(initializer, file = "") {
|
|
1881
1908
|
if (!initializer) return null;
|
|
1882
1909
|
let value;
|
|
1883
|
-
if (
|
|
1910
|
+
if (ts4.isStringLiteral(initializer)) {
|
|
1884
1911
|
value = initializer.text;
|
|
1885
|
-
} else if (
|
|
1912
|
+
} else if (ts4.isNumericLiteral(initializer)) {
|
|
1886
1913
|
value = Number(initializer.text);
|
|
1887
|
-
} else if (initializer.kind ===
|
|
1914
|
+
} else if (initializer.kind === ts4.SyntaxKind.TrueKeyword) {
|
|
1888
1915
|
value = true;
|
|
1889
|
-
} else if (initializer.kind ===
|
|
1916
|
+
} else if (initializer.kind === ts4.SyntaxKind.FalseKeyword) {
|
|
1890
1917
|
value = false;
|
|
1891
|
-
} else if (initializer.kind ===
|
|
1918
|
+
} else if (initializer.kind === ts4.SyntaxKind.NullKeyword) {
|
|
1892
1919
|
value = null;
|
|
1893
|
-
} else if (
|
|
1894
|
-
if (initializer.operator ===
|
|
1920
|
+
} else if (ts4.isPrefixUnaryExpression(initializer)) {
|
|
1921
|
+
if (initializer.operator === ts4.SyntaxKind.MinusToken && ts4.isNumericLiteral(initializer.operand)) {
|
|
1895
1922
|
value = -Number(initializer.operand.text);
|
|
1896
1923
|
}
|
|
1897
1924
|
}
|
|
@@ -1913,28 +1940,28 @@ function extractDefaultValueAnnotation(initializer, file = "") {
|
|
|
1913
1940
|
|
|
1914
1941
|
// src/analyzer/class-analyzer.ts
|
|
1915
1942
|
function isObjectType(type) {
|
|
1916
|
-
return !!(type.flags &
|
|
1943
|
+
return !!(type.flags & ts5.TypeFlags.Object);
|
|
1917
1944
|
}
|
|
1918
1945
|
function isIntersectionType(type) {
|
|
1919
|
-
return !!(type.flags &
|
|
1946
|
+
return !!(type.flags & ts5.TypeFlags.Intersection);
|
|
1920
1947
|
}
|
|
1921
1948
|
function isResolvableObjectLikeAliasTypeNode(typeNode) {
|
|
1922
|
-
if (
|
|
1949
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
1923
1950
|
return isResolvableObjectLikeAliasTypeNode(typeNode.type);
|
|
1924
1951
|
}
|
|
1925
|
-
if (
|
|
1952
|
+
if (ts5.isTypeLiteralNode(typeNode) || ts5.isTypeReferenceNode(typeNode)) {
|
|
1926
1953
|
return true;
|
|
1927
1954
|
}
|
|
1928
|
-
return
|
|
1955
|
+
return ts5.isIntersectionTypeNode(typeNode) && typeNode.types.length > 0 && typeNode.types.every((member) => isResolvableObjectLikeAliasTypeNode(member));
|
|
1929
1956
|
}
|
|
1930
1957
|
function isSemanticallyPlainObjectLikeType(type, checker) {
|
|
1931
1958
|
if (isIntersectionType(type)) {
|
|
1932
1959
|
return type.types.length > 0 && type.types.every((member) => isSemanticallyPlainObjectLikeType(member, checker));
|
|
1933
1960
|
}
|
|
1934
|
-
return isObjectType(type) && checker.getSignaturesOfType(type,
|
|
1961
|
+
return isObjectType(type) && checker.getSignaturesOfType(type, ts5.SignatureKind.Call).length === 0 && checker.getSignaturesOfType(type, ts5.SignatureKind.Construct).length === 0 && !checker.isArrayType(type) && !checker.isTupleType(type);
|
|
1935
1962
|
}
|
|
1936
1963
|
function isTypeReference(type) {
|
|
1937
|
-
return !!(type.flags &
|
|
1964
|
+
return !!(type.flags & ts5.TypeFlags.Object) && !!(type.objectFlags & ts5.ObjectFlags.Reference);
|
|
1938
1965
|
}
|
|
1939
1966
|
var RESOLVING_TYPE_PLACEHOLDER = {
|
|
1940
1967
|
kind: "object",
|
|
@@ -1960,6 +1987,21 @@ function createAnalyzerMetadataPolicy(input, discriminator) {
|
|
|
1960
1987
|
discriminator
|
|
1961
1988
|
};
|
|
1962
1989
|
}
|
|
1990
|
+
var DEDUPLICATABLE_DIAGNOSTIC_CODES = /* @__PURE__ */ new Set([
|
|
1991
|
+
"SYNTHETIC_SETUP_FAILURE",
|
|
1992
|
+
"UNSUPPORTED_CUSTOM_TYPE_OVERRIDE"
|
|
1993
|
+
]);
|
|
1994
|
+
function deduplicateDiagnostics(diagnostics) {
|
|
1995
|
+
if (diagnostics.length <= 1) return diagnostics;
|
|
1996
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1997
|
+
return diagnostics.filter((d) => {
|
|
1998
|
+
if (!DEDUPLICATABLE_DIAGNOSTIC_CODES.has(d.code)) return true;
|
|
1999
|
+
const key = `${d.code}\0${d.message}`;
|
|
2000
|
+
if (seen.has(key)) return false;
|
|
2001
|
+
seen.add(key);
|
|
2002
|
+
return true;
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
1963
2005
|
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
1964
2006
|
const analysis = analyzeMetadataForNodeWithChecker({
|
|
1965
2007
|
checker,
|
|
@@ -1996,10 +2038,121 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
|
|
|
1996
2038
|
}
|
|
1997
2039
|
return resolvedMetadata;
|
|
1998
2040
|
}
|
|
2041
|
+
var INHERITABLE_TYPE_ANNOTATION_KINDS = /* @__PURE__ */ new Set(["format"]);
|
|
2042
|
+
function getInheritableAnnotationStringValue(annotation) {
|
|
2043
|
+
if (annotation.annotationKind === "format") return annotation.value;
|
|
2044
|
+
return void 0;
|
|
2045
|
+
}
|
|
2046
|
+
function isOverridingInheritableAnnotation(annotation) {
|
|
2047
|
+
const value = getInheritableAnnotationStringValue(annotation);
|
|
2048
|
+
if (value === void 0) return true;
|
|
2049
|
+
return value.trim().length > 0;
|
|
2050
|
+
}
|
|
2051
|
+
function collectInheritedTypeAnnotations(derivedDecl, existingAnnotations, checker, extensionRegistry) {
|
|
2052
|
+
const existingKinds = new Set(
|
|
2053
|
+
existingAnnotations.filter(isOverridingInheritableAnnotation).map((a) => a.annotationKind)
|
|
2054
|
+
);
|
|
2055
|
+
const needed = /* @__PURE__ */ new Set();
|
|
2056
|
+
for (const kind of INHERITABLE_TYPE_ANNOTATION_KINDS) {
|
|
2057
|
+
if (!existingKinds.has(kind)) needed.add(kind);
|
|
2058
|
+
}
|
|
2059
|
+
if (needed.size === 0) return [];
|
|
2060
|
+
const inherited = [];
|
|
2061
|
+
const seen = /* @__PURE__ */ new Set([derivedDecl]);
|
|
2062
|
+
const queue = [];
|
|
2063
|
+
const resolveSymbolTarget = (sym) => {
|
|
2064
|
+
if ((sym.flags & ts5.SymbolFlags.Alias) === 0) return sym;
|
|
2065
|
+
try {
|
|
2066
|
+
return checker.getAliasedSymbol(sym);
|
|
2067
|
+
} catch {
|
|
2068
|
+
return sym;
|
|
2069
|
+
}
|
|
2070
|
+
};
|
|
2071
|
+
const isObjectShapedTypeAlias = (alias) => {
|
|
2072
|
+
const type = checker.getTypeFromTypeNode(alias.type);
|
|
2073
|
+
if ((type.flags & ts5.TypeFlags.Object) !== 0) return true;
|
|
2074
|
+
if (type.isIntersection()) return true;
|
|
2075
|
+
return false;
|
|
2076
|
+
};
|
|
2077
|
+
const enqueueCandidate = (baseDecl, fromTypeAliasRhs) => {
|
|
2078
|
+
if (seen.has(baseDecl)) return;
|
|
2079
|
+
if (ts5.isClassDeclaration(baseDecl) || ts5.isInterfaceDeclaration(baseDecl)) {
|
|
2080
|
+
seen.add(baseDecl);
|
|
2081
|
+
queue.push(baseDecl);
|
|
2082
|
+
return;
|
|
2083
|
+
}
|
|
2084
|
+
if (ts5.isTypeAliasDeclaration(baseDecl)) {
|
|
2085
|
+
if (!fromTypeAliasRhs && !isObjectShapedTypeAlias(baseDecl)) return;
|
|
2086
|
+
seen.add(baseDecl);
|
|
2087
|
+
queue.push(baseDecl);
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
2090
|
+
const enqueueBasesOf = (decl) => {
|
|
2091
|
+
if (ts5.isTypeAliasDeclaration(decl)) {
|
|
2092
|
+
const rhs = decl.type;
|
|
2093
|
+
if (!ts5.isTypeReferenceNode(rhs)) return;
|
|
2094
|
+
const sym = checker.getSymbolAtLocation(rhs.typeName);
|
|
2095
|
+
if (!sym) return;
|
|
2096
|
+
const target = resolveSymbolTarget(sym);
|
|
2097
|
+
for (const baseDecl of target.declarations ?? []) {
|
|
2098
|
+
enqueueCandidate(
|
|
2099
|
+
baseDecl,
|
|
2100
|
+
/*fromTypeAliasRhs*/
|
|
2101
|
+
true
|
|
2102
|
+
);
|
|
2103
|
+
}
|
|
2104
|
+
return;
|
|
2105
|
+
}
|
|
2106
|
+
const heritageClauses = decl.heritageClauses;
|
|
2107
|
+
if (!heritageClauses) return;
|
|
2108
|
+
for (const clause of heritageClauses) {
|
|
2109
|
+
if (clause.token !== ts5.SyntaxKind.ExtendsKeyword) continue;
|
|
2110
|
+
for (const typeExpr of clause.types) {
|
|
2111
|
+
const sym = checker.getSymbolAtLocation(typeExpr.expression);
|
|
2112
|
+
if (!sym) continue;
|
|
2113
|
+
const target = resolveSymbolTarget(sym);
|
|
2114
|
+
for (const baseDecl of target.declarations ?? []) {
|
|
2115
|
+
enqueueCandidate(
|
|
2116
|
+
baseDecl,
|
|
2117
|
+
/*fromTypeAliasRhs*/
|
|
2118
|
+
false
|
|
2119
|
+
);
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
};
|
|
2124
|
+
enqueueBasesOf(derivedDecl);
|
|
2125
|
+
for (let queueIndex = 0; queueIndex < queue.length && needed.size > 0; queueIndex++) {
|
|
2126
|
+
const baseDecl = queue[queueIndex];
|
|
2127
|
+
if (baseDecl === void 0) continue;
|
|
2128
|
+
const baseFile = baseDecl.getSourceFile().fileName;
|
|
2129
|
+
const baseAnnotations = extractJSDocAnnotationNodes(
|
|
2130
|
+
baseDecl,
|
|
2131
|
+
baseFile,
|
|
2132
|
+
makeParseOptions(extensionRegistry)
|
|
2133
|
+
);
|
|
2134
|
+
for (const annotation of baseAnnotations) {
|
|
2135
|
+
if (!needed.has(annotation.annotationKind)) continue;
|
|
2136
|
+
if (!isOverridingInheritableAnnotation(annotation)) continue;
|
|
2137
|
+
inherited.push(annotation);
|
|
2138
|
+
needed.delete(annotation.annotationKind);
|
|
2139
|
+
}
|
|
2140
|
+
if (needed.size > 0) {
|
|
2141
|
+
enqueueBasesOf(baseDecl);
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
return inherited;
|
|
2145
|
+
}
|
|
2146
|
+
function extractNamedTypeAnnotations(namedDecl, checker, file, extensionRegistry) {
|
|
2147
|
+
const local = extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry));
|
|
2148
|
+
const inherited = collectInheritedTypeAnnotations(namedDecl, local, checker, extensionRegistry);
|
|
2149
|
+
if (inherited.length === 0) return [...local];
|
|
2150
|
+
return [...local, ...inherited];
|
|
2151
|
+
}
|
|
1999
2152
|
function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2000
2153
|
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
2001
2154
|
const declarationType = checker.getTypeAtLocation(declaration);
|
|
2002
|
-
const logicalName =
|
|
2155
|
+
const logicalName = ts5.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
|
|
2003
2156
|
const docResult = extractJSDocParseResult(
|
|
2004
2157
|
declaration,
|
|
2005
2158
|
file,
|
|
@@ -2041,13 +2194,19 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
2041
2194
|
file,
|
|
2042
2195
|
makeParseOptions(extensionRegistry, void 0, checker, classType, classType)
|
|
2043
2196
|
);
|
|
2044
|
-
const
|
|
2197
|
+
const inheritedClassAnnotations = collectInheritedTypeAnnotations(
|
|
2198
|
+
classDecl,
|
|
2199
|
+
classDoc.annotations,
|
|
2200
|
+
checker,
|
|
2201
|
+
extensionRegistry
|
|
2202
|
+
);
|
|
2203
|
+
const annotations = [...classDoc.annotations, ...inheritedClassAnnotations];
|
|
2045
2204
|
diagnostics.push(...classDoc.diagnostics);
|
|
2046
2205
|
const visiting = /* @__PURE__ */ new Set();
|
|
2047
2206
|
const instanceMethods = [];
|
|
2048
2207
|
const staticMethods = [];
|
|
2049
2208
|
for (const member of classDecl.members) {
|
|
2050
|
-
if (
|
|
2209
|
+
if (ts5.isPropertyDeclaration(member)) {
|
|
2051
2210
|
const fieldNode = analyzeFieldToIR(
|
|
2052
2211
|
member,
|
|
2053
2212
|
checker,
|
|
@@ -2063,10 +2222,10 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
2063
2222
|
fields.push(fieldNode);
|
|
2064
2223
|
fieldLayouts.push({});
|
|
2065
2224
|
}
|
|
2066
|
-
} else if (
|
|
2225
|
+
} else if (ts5.isMethodDeclaration(member)) {
|
|
2067
2226
|
const methodInfo = analyzeMethod(member, checker);
|
|
2068
2227
|
if (methodInfo) {
|
|
2069
|
-
const isStatic = member.modifiers?.some((m) => m.kind ===
|
|
2228
|
+
const isStatic = member.modifiers?.some((m) => m.kind === ts5.SyntaxKind.StaticKeyword);
|
|
2070
2229
|
if (isStatic) {
|
|
2071
2230
|
staticMethods.push(methodInfo);
|
|
2072
2231
|
} else {
|
|
@@ -2098,6 +2257,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
2098
2257
|
hostType: classType
|
|
2099
2258
|
}
|
|
2100
2259
|
);
|
|
2260
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
2101
2261
|
return {
|
|
2102
2262
|
name,
|
|
2103
2263
|
...metadata !== void 0 && { metadata },
|
|
@@ -2105,7 +2265,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
2105
2265
|
fieldLayouts,
|
|
2106
2266
|
typeRegistry,
|
|
2107
2267
|
...annotations.length > 0 && { annotations },
|
|
2108
|
-
...
|
|
2268
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
2109
2269
|
instanceMethods,
|
|
2110
2270
|
staticMethods
|
|
2111
2271
|
};
|
|
@@ -2125,11 +2285,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2125
2285
|
file,
|
|
2126
2286
|
makeParseOptions(extensionRegistry, void 0, checker, interfaceType, interfaceType)
|
|
2127
2287
|
);
|
|
2128
|
-
const
|
|
2288
|
+
const inheritedInterfaceAnnotations = collectInheritedTypeAnnotations(
|
|
2289
|
+
interfaceDecl,
|
|
2290
|
+
interfaceDoc.annotations,
|
|
2291
|
+
checker,
|
|
2292
|
+
extensionRegistry
|
|
2293
|
+
);
|
|
2294
|
+
const annotations = [
|
|
2295
|
+
...interfaceDoc.annotations,
|
|
2296
|
+
...inheritedInterfaceAnnotations
|
|
2297
|
+
];
|
|
2129
2298
|
diagnostics.push(...interfaceDoc.diagnostics);
|
|
2130
2299
|
const visiting = /* @__PURE__ */ new Set();
|
|
2131
2300
|
for (const member of interfaceDecl.members) {
|
|
2132
|
-
if (
|
|
2301
|
+
if (ts5.isPropertySignature(member)) {
|
|
2133
2302
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
2134
2303
|
member,
|
|
2135
2304
|
checker,
|
|
@@ -2170,6 +2339,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2170
2339
|
hostType: interfaceType
|
|
2171
2340
|
}
|
|
2172
2341
|
);
|
|
2342
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
2173
2343
|
return {
|
|
2174
2344
|
name,
|
|
2175
2345
|
...metadata !== void 0 && { metadata },
|
|
@@ -2177,7 +2347,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2177
2347
|
fieldLayouts,
|
|
2178
2348
|
typeRegistry,
|
|
2179
2349
|
...annotations.length > 0 && { annotations },
|
|
2180
|
-
...
|
|
2350
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
2181
2351
|
instanceMethods: [],
|
|
2182
2352
|
staticMethods: []
|
|
2183
2353
|
};
|
|
@@ -2187,7 +2357,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
2187
2357
|
if (members === null) {
|
|
2188
2358
|
const sourceFile = typeAlias.getSourceFile();
|
|
2189
2359
|
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
2190
|
-
const kindDesc =
|
|
2360
|
+
const kindDesc = ts5.SyntaxKind[typeAlias.type.kind] ?? "unknown";
|
|
2191
2361
|
return {
|
|
2192
2362
|
ok: false,
|
|
2193
2363
|
kind: "not-object-like",
|
|
@@ -2222,7 +2392,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
2222
2392
|
diagnostics.push(...typeAliasDoc.diagnostics);
|
|
2223
2393
|
const visiting = /* @__PURE__ */ new Set();
|
|
2224
2394
|
for (const member of members) {
|
|
2225
|
-
if (
|
|
2395
|
+
if (ts5.isPropertySignature(member)) {
|
|
2226
2396
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
2227
2397
|
member,
|
|
2228
2398
|
checker,
|
|
@@ -2262,6 +2432,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
2262
2432
|
hostType: aliasType
|
|
2263
2433
|
}
|
|
2264
2434
|
);
|
|
2435
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
2265
2436
|
return {
|
|
2266
2437
|
ok: true,
|
|
2267
2438
|
analysis: {
|
|
@@ -2271,7 +2442,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
2271
2442
|
fieldLayouts: specializedFields.map(() => ({})),
|
|
2272
2443
|
typeRegistry,
|
|
2273
2444
|
...annotations.length > 0 && { annotations },
|
|
2274
|
-
...
|
|
2445
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
2275
2446
|
instanceMethods: [],
|
|
2276
2447
|
staticMethods: []
|
|
2277
2448
|
}
|
|
@@ -2289,13 +2460,13 @@ function makeAnalysisDiagnostic(code, message, primaryLocation, relatedLocations
|
|
|
2289
2460
|
function getLeadingParsedTags(node) {
|
|
2290
2461
|
const sourceFile = node.getSourceFile();
|
|
2291
2462
|
const sourceText = sourceFile.getFullText();
|
|
2292
|
-
const commentRanges =
|
|
2463
|
+
const commentRanges = ts5.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
2293
2464
|
if (commentRanges === void 0) {
|
|
2294
2465
|
return [];
|
|
2295
2466
|
}
|
|
2296
2467
|
const parsedTags = [];
|
|
2297
2468
|
for (const range of commentRanges) {
|
|
2298
|
-
if (range.kind !==
|
|
2469
|
+
if (range.kind !== ts5.SyntaxKind.MultiLineCommentTrivia) {
|
|
2299
2470
|
continue;
|
|
2300
2471
|
}
|
|
2301
2472
|
const commentText = sourceText.slice(range.pos, range.end);
|
|
@@ -2313,19 +2484,19 @@ function resolveDiscriminatorProperty(node, checker, fieldName) {
|
|
|
2313
2484
|
return null;
|
|
2314
2485
|
}
|
|
2315
2486
|
const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.find(
|
|
2316
|
-
(candidate) =>
|
|
2487
|
+
(candidate) => ts5.isPropertyDeclaration(candidate) || ts5.isPropertySignature(candidate)
|
|
2317
2488
|
) ?? propertySymbol.declarations?.[0];
|
|
2318
2489
|
return {
|
|
2319
2490
|
declaration,
|
|
2320
2491
|
type: checker.getTypeOfSymbolAtLocation(propertySymbol, declaration ?? node),
|
|
2321
|
-
optional: !!(propertySymbol.flags &
|
|
2492
|
+
optional: !!(propertySymbol.flags & ts5.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
|
|
2322
2493
|
};
|
|
2323
2494
|
}
|
|
2324
2495
|
function isLocalTypeParameterName(node, typeParameterName) {
|
|
2325
2496
|
return node.typeParameters?.some((typeParameter) => typeParameter.name.text === typeParameterName) ?? false;
|
|
2326
2497
|
}
|
|
2327
2498
|
function isNullishSemanticType(type) {
|
|
2328
|
-
if (type.flags & (
|
|
2499
|
+
if (type.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined | ts5.TypeFlags.Void | ts5.TypeFlags.Unknown | ts5.TypeFlags.Any)) {
|
|
2329
2500
|
return true;
|
|
2330
2501
|
}
|
|
2331
2502
|
return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
|
|
@@ -2335,7 +2506,7 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
|
|
|
2335
2506
|
return false;
|
|
2336
2507
|
}
|
|
2337
2508
|
seen.add(type);
|
|
2338
|
-
if (type.flags &
|
|
2509
|
+
if (type.flags & ts5.TypeFlags.StringLike) {
|
|
2339
2510
|
return true;
|
|
2340
2511
|
}
|
|
2341
2512
|
if (type.isUnion()) {
|
|
@@ -2348,13 +2519,13 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
|
|
|
2348
2519
|
return false;
|
|
2349
2520
|
}
|
|
2350
2521
|
function getObjectLikeTypeAliasMembers(typeNode) {
|
|
2351
|
-
if (
|
|
2522
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
2352
2523
|
return getObjectLikeTypeAliasMembers(typeNode.type);
|
|
2353
2524
|
}
|
|
2354
|
-
if (
|
|
2525
|
+
if (ts5.isTypeLiteralNode(typeNode)) {
|
|
2355
2526
|
return [...typeNode.members];
|
|
2356
2527
|
}
|
|
2357
|
-
if (
|
|
2528
|
+
if (ts5.isIntersectionTypeNode(typeNode)) {
|
|
2358
2529
|
const members = [];
|
|
2359
2530
|
for (const intersectionMember of typeNode.types) {
|
|
2360
2531
|
const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
|
|
@@ -2517,7 +2688,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, check
|
|
|
2517
2688
|
}
|
|
2518
2689
|
if (propertyType.isUnion()) {
|
|
2519
2690
|
const nonNullMembers = propertyType.types.filter(
|
|
2520
|
-
(member) => !(member.flags & (
|
|
2691
|
+
(member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
2521
2692
|
);
|
|
2522
2693
|
if (nonNullMembers.length > 0 && nonNullMembers.every((member) => member.isStringLiteral())) {
|
|
2523
2694
|
diagnostics.push(
|
|
@@ -2566,13 +2737,13 @@ function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__
|
|
|
2566
2737
|
seen.add(type);
|
|
2567
2738
|
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
2568
2739
|
if (symbol !== void 0) {
|
|
2569
|
-
const aliased = symbol.flags &
|
|
2740
|
+
const aliased = symbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : void 0;
|
|
2570
2741
|
const targetSymbol = aliased ?? symbol;
|
|
2571
2742
|
const declaration = targetSymbol.declarations?.find(
|
|
2572
|
-
(candidate) =>
|
|
2743
|
+
(candidate) => ts5.isClassDeclaration(candidate) || ts5.isInterfaceDeclaration(candidate) || ts5.isTypeAliasDeclaration(candidate) || ts5.isEnumDeclaration(candidate)
|
|
2573
2744
|
);
|
|
2574
2745
|
if (declaration !== void 0) {
|
|
2575
|
-
if (
|
|
2746
|
+
if (ts5.isTypeAliasDeclaration(declaration) && ts5.isTypeReferenceNode(declaration.type) && checker.getTypeFromTypeNode(declaration.type) !== type) {
|
|
2576
2747
|
return resolveNamedDiscriminatorDeclaration(
|
|
2577
2748
|
checker.getTypeFromTypeNode(declaration.type),
|
|
2578
2749
|
checker,
|
|
@@ -2600,7 +2771,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
|
|
|
2600
2771
|
}
|
|
2601
2772
|
if (boundType.isUnion()) {
|
|
2602
2773
|
const nonNullMembers = boundType.types.filter(
|
|
2603
|
-
(member) => !(member.flags & (
|
|
2774
|
+
(member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
2604
2775
|
);
|
|
2605
2776
|
if (nonNullMembers.every((member) => member.isStringLiteral())) {
|
|
2606
2777
|
diagnostics.push(
|
|
@@ -2645,7 +2816,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
|
|
|
2645
2816
|
return null;
|
|
2646
2817
|
}
|
|
2647
2818
|
function getDeclarationName(node) {
|
|
2648
|
-
if (
|
|
2819
|
+
if (ts5.isClassDeclaration(node) || ts5.isInterfaceDeclaration(node) || ts5.isTypeAliasDeclaration(node) || ts5.isEnumDeclaration(node)) {
|
|
2649
2820
|
return node.name?.text ?? "anonymous";
|
|
2650
2821
|
}
|
|
2651
2822
|
return "anonymous";
|
|
@@ -2700,11 +2871,11 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
2700
2871
|
if (sourceTypeNode === void 0) {
|
|
2701
2872
|
return [];
|
|
2702
2873
|
}
|
|
2703
|
-
const unwrapParentheses = (typeNode) =>
|
|
2874
|
+
const unwrapParentheses = (typeNode) => ts5.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
|
|
2704
2875
|
const directTypeNode = unwrapParentheses(sourceTypeNode);
|
|
2705
|
-
const referenceTypeNode =
|
|
2876
|
+
const referenceTypeNode = ts5.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
|
|
2706
2877
|
const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
|
|
2707
|
-
return
|
|
2878
|
+
return ts5.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
|
|
2708
2879
|
})();
|
|
2709
2880
|
if (referenceTypeNode?.typeArguments === void 0) {
|
|
2710
2881
|
return [];
|
|
@@ -2712,7 +2883,7 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
2712
2883
|
return referenceTypeNode.typeArguments.map((argumentNode) => {
|
|
2713
2884
|
const argumentType = checker.getTypeFromTypeNode(argumentNode);
|
|
2714
2885
|
const baseSymbol = argumentType.aliasSymbol ?? argumentType.getSymbol();
|
|
2715
|
-
const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags &
|
|
2886
|
+
const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(baseSymbol) : baseSymbol;
|
|
2716
2887
|
const argumentDecl = argumentSymbol?.declarations?.[0];
|
|
2717
2888
|
if (argumentDecl !== void 0 && argumentDecl.getSourceFile().fileName !== file) {
|
|
2718
2889
|
const argumentName = argumentSymbol?.getName() ?? baseSymbol?.getName();
|
|
@@ -2775,7 +2946,7 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
|
|
|
2775
2946
|
);
|
|
2776
2947
|
}
|
|
2777
2948
|
function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
2778
|
-
if (!
|
|
2949
|
+
if (!ts5.isIdentifier(prop.name)) {
|
|
2779
2950
|
return null;
|
|
2780
2951
|
}
|
|
2781
2952
|
const name = prop.name.text;
|
|
@@ -2902,7 +3073,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
|
|
|
2902
3073
|
const seen = /* @__PURE__ */ new Set();
|
|
2903
3074
|
const duplicates = /* @__PURE__ */ new Set();
|
|
2904
3075
|
for (const member of members) {
|
|
2905
|
-
if (!
|
|
3076
|
+
if (!ts5.isPropertySignature(member)) {
|
|
2906
3077
|
continue;
|
|
2907
3078
|
}
|
|
2908
3079
|
const name = getAnalyzableObjectLikePropertyName(member.name);
|
|
@@ -2918,7 +3089,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
|
|
|
2918
3089
|
return [...duplicates].sort();
|
|
2919
3090
|
}
|
|
2920
3091
|
function getAnalyzableObjectLikePropertyName(name) {
|
|
2921
|
-
if (
|
|
3092
|
+
if (ts5.isIdentifier(name) || ts5.isStringLiteral(name) || ts5.isNumericLiteral(name)) {
|
|
2922
3093
|
return name.text;
|
|
2923
3094
|
}
|
|
2924
3095
|
return null;
|
|
@@ -3013,28 +3184,28 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3013
3184
|
if (primitiveAlias) {
|
|
3014
3185
|
return primitiveAlias;
|
|
3015
3186
|
}
|
|
3016
|
-
if (
|
|
3187
|
+
if (_isIntegerBrandedType(type)) {
|
|
3017
3188
|
return { kind: "primitive", primitiveKind: "integer" };
|
|
3018
3189
|
}
|
|
3019
|
-
if (type.flags &
|
|
3190
|
+
if (type.flags & ts5.TypeFlags.String) {
|
|
3020
3191
|
return { kind: "primitive", primitiveKind: "string" };
|
|
3021
3192
|
}
|
|
3022
|
-
if (type.flags &
|
|
3193
|
+
if (type.flags & ts5.TypeFlags.Number) {
|
|
3023
3194
|
return { kind: "primitive", primitiveKind: "number" };
|
|
3024
3195
|
}
|
|
3025
|
-
if (type.flags & (
|
|
3196
|
+
if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
|
|
3026
3197
|
return { kind: "primitive", primitiveKind: "bigint" };
|
|
3027
3198
|
}
|
|
3028
|
-
if (type.flags &
|
|
3199
|
+
if (type.flags & ts5.TypeFlags.Boolean) {
|
|
3029
3200
|
return { kind: "primitive", primitiveKind: "boolean" };
|
|
3030
3201
|
}
|
|
3031
|
-
if (type.flags &
|
|
3202
|
+
if (type.flags & ts5.TypeFlags.Null) {
|
|
3032
3203
|
return { kind: "primitive", primitiveKind: "null" };
|
|
3033
3204
|
}
|
|
3034
|
-
if (type.flags &
|
|
3205
|
+
if (type.flags & ts5.TypeFlags.Undefined) {
|
|
3035
3206
|
return { kind: "primitive", primitiveKind: "null" };
|
|
3036
3207
|
}
|
|
3037
|
-
if (type.flags &
|
|
3208
|
+
if (type.flags & ts5.TypeFlags.Void) {
|
|
3038
3209
|
return { kind: "primitive", primitiveKind: "null" };
|
|
3039
3210
|
}
|
|
3040
3211
|
if (type.isStringLiteral()) {
|
|
@@ -3121,10 +3292,10 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3121
3292
|
return { kind: "primitive", primitiveKind: "string" };
|
|
3122
3293
|
}
|
|
3123
3294
|
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3124
|
-
if (!(type.flags & (
|
|
3295
|
+
if (!(type.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null)) && !_isIntegerBrandedType(type)) {
|
|
3125
3296
|
return null;
|
|
3126
3297
|
}
|
|
3127
|
-
const aliasDecl = type.aliasSymbol?.declarations?.find(
|
|
3298
|
+
const aliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration) ?? getReferencedTypeAliasDeclaration(sourceNode, checker);
|
|
3128
3299
|
if (!aliasDecl) {
|
|
3129
3300
|
return null;
|
|
3130
3301
|
}
|
|
@@ -3135,11 +3306,18 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
3135
3306
|
...extractJSDocConstraintNodes(aliasDecl, file, makeParseOptions(extensionRegistry)),
|
|
3136
3307
|
...extractTypeAliasConstraintNodes(aliasDecl.type, checker, file, extensionRegistry)
|
|
3137
3308
|
];
|
|
3138
|
-
const
|
|
3309
|
+
const localAnnotations = extractJSDocAnnotationNodes(
|
|
3139
3310
|
aliasDecl,
|
|
3140
3311
|
file,
|
|
3141
3312
|
makeParseOptions(extensionRegistry)
|
|
3142
3313
|
);
|
|
3314
|
+
const inheritedAnnotations = collectInheritedTypeAnnotations(
|
|
3315
|
+
aliasDecl,
|
|
3316
|
+
localAnnotations,
|
|
3317
|
+
checker,
|
|
3318
|
+
extensionRegistry
|
|
3319
|
+
);
|
|
3320
|
+
const annotations = [...localAnnotations, ...inheritedAnnotations];
|
|
3143
3321
|
const metadata = resolveNodeMetadata(
|
|
3144
3322
|
metadataPolicy,
|
|
3145
3323
|
"type",
|
|
@@ -3174,8 +3352,8 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
3174
3352
|
return { kind: "reference", name: aliasName, typeArguments: [] };
|
|
3175
3353
|
}
|
|
3176
3354
|
function getReferencedTypeAliasDeclaration(sourceNode, checker) {
|
|
3177
|
-
const typeNode = sourceNode && (
|
|
3178
|
-
if (!typeNode || !
|
|
3355
|
+
const typeNode = sourceNode && (ts5.isPropertyDeclaration(sourceNode) || ts5.isPropertySignature(sourceNode) || ts5.isParameter(sourceNode)) ? sourceNode.type : void 0;
|
|
3356
|
+
if (!typeNode || !ts5.isTypeReferenceNode(typeNode)) {
|
|
3179
3357
|
return void 0;
|
|
3180
3358
|
}
|
|
3181
3359
|
return getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -3196,7 +3374,7 @@ function resolveNamedTypeWithSourceRecovery(type, sourceNode, checker) {
|
|
|
3196
3374
|
return { typeName: refAliasDecl.name.text, namedDecl: refAliasDecl };
|
|
3197
3375
|
}
|
|
3198
3376
|
function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
3199
|
-
if (!
|
|
3377
|
+
if (!ts5.isTypeReferenceNode(typeNode)) {
|
|
3200
3378
|
return false;
|
|
3201
3379
|
}
|
|
3202
3380
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -3204,10 +3382,10 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
3204
3382
|
return false;
|
|
3205
3383
|
}
|
|
3206
3384
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
3207
|
-
return !!(resolved.flags & (
|
|
3385
|
+
return !!(resolved.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null));
|
|
3208
3386
|
}
|
|
3209
3387
|
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics, visitedAliases = /* @__PURE__ */ new Set()) {
|
|
3210
|
-
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(
|
|
3388
|
+
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration);
|
|
3211
3389
|
if (nestedAliasDecl !== void 0 && !visitedAliases.has(nestedAliasDecl)) {
|
|
3212
3390
|
visitedAliases.add(nestedAliasDecl);
|
|
3213
3391
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -3222,22 +3400,22 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
3222
3400
|
visitedAliases
|
|
3223
3401
|
);
|
|
3224
3402
|
}
|
|
3225
|
-
if (
|
|
3403
|
+
if (_isIntegerBrandedType(type)) {
|
|
3226
3404
|
return { kind: "primitive", primitiveKind: "integer" };
|
|
3227
3405
|
}
|
|
3228
|
-
if (type.flags &
|
|
3406
|
+
if (type.flags & ts5.TypeFlags.String) {
|
|
3229
3407
|
return { kind: "primitive", primitiveKind: "string" };
|
|
3230
3408
|
}
|
|
3231
|
-
if (type.flags &
|
|
3409
|
+
if (type.flags & ts5.TypeFlags.Number) {
|
|
3232
3410
|
return { kind: "primitive", primitiveKind: "number" };
|
|
3233
3411
|
}
|
|
3234
|
-
if (type.flags & (
|
|
3412
|
+
if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
|
|
3235
3413
|
return { kind: "primitive", primitiveKind: "bigint" };
|
|
3236
3414
|
}
|
|
3237
|
-
if (type.flags &
|
|
3415
|
+
if (type.flags & ts5.TypeFlags.Boolean) {
|
|
3238
3416
|
return { kind: "primitive", primitiveKind: "boolean" };
|
|
3239
3417
|
}
|
|
3240
|
-
if (type.flags &
|
|
3418
|
+
if (type.flags & ts5.TypeFlags.Null) {
|
|
3241
3419
|
return { kind: "primitive", primitiveKind: "null" };
|
|
3242
3420
|
}
|
|
3243
3421
|
return resolveTypeNode(
|
|
@@ -3257,7 +3435,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3257
3435
|
let typeName = null;
|
|
3258
3436
|
let namedDecl;
|
|
3259
3437
|
if (recovered !== null) {
|
|
3260
|
-
const recoveredAliasDecl =
|
|
3438
|
+
const recoveredAliasDecl = ts5.isTypeAliasDeclaration(recovered.namedDecl) ? recovered.namedDecl : void 0;
|
|
3261
3439
|
if (recoveredAliasDecl !== void 0) {
|
|
3262
3440
|
const aliasUnderlyingType = checker.getTypeFromTypeNode(recoveredAliasDecl.type);
|
|
3263
3441
|
const isNonGeneric = recoveredAliasDecl.typeParameters === void 0 || recoveredAliasDecl.typeParameters.length === 0;
|
|
@@ -3279,13 +3457,13 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3279
3457
|
(memberTypeNode) => !isNullishTypeNode(resolveAliasedTypeNode(memberTypeNode, checker))
|
|
3280
3458
|
);
|
|
3281
3459
|
const nonNullTypes = allTypes.filter(
|
|
3282
|
-
(memberType) => !(memberType.flags & (
|
|
3460
|
+
(memberType) => !(memberType.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
3283
3461
|
);
|
|
3284
3462
|
const nonNullMembers = nonNullTypes.map((memberType, index) => ({
|
|
3285
3463
|
memberType,
|
|
3286
3464
|
sourceNode: nonNullSourceNodes.length === nonNullTypes.length ? nonNullSourceNodes[index] : void 0
|
|
3287
3465
|
}));
|
|
3288
|
-
const hasNull = allTypes.some((t) => t.flags &
|
|
3466
|
+
const hasNull = allTypes.some((t) => t.flags & ts5.TypeFlags.Null);
|
|
3289
3467
|
const memberDisplayNames = /* @__PURE__ */ new Map();
|
|
3290
3468
|
if (namedDecl) {
|
|
3291
3469
|
for (const [value, label] of extractDisplayNameMetadata(namedDecl).memberDisplayNames) {
|
|
@@ -3305,7 +3483,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3305
3483
|
if (existing !== void 0 && existing.type !== RESOLVING_TYPE_PLACEHOLDER) {
|
|
3306
3484
|
return { kind: "reference", name: typeName, typeArguments: [] };
|
|
3307
3485
|
}
|
|
3308
|
-
const annotations = namedDecl ?
|
|
3486
|
+
const annotations = namedDecl ? extractNamedTypeAnnotations(namedDecl, checker, file, extensionRegistry) : void 0;
|
|
3309
3487
|
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3310
3488
|
metadataPolicy,
|
|
3311
3489
|
"type",
|
|
@@ -3332,7 +3510,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3332
3510
|
const displayName = memberDisplayNames.get(String(value));
|
|
3333
3511
|
return displayName !== void 0 ? { value, displayName } : { value };
|
|
3334
3512
|
});
|
|
3335
|
-
const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags &
|
|
3513
|
+
const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags & ts5.TypeFlags.BooleanLiteral);
|
|
3336
3514
|
if (isBooleanUnion2) {
|
|
3337
3515
|
const boolNode = { kind: "primitive", primitiveKind: "boolean" };
|
|
3338
3516
|
const result = hasNull ? {
|
|
@@ -3424,7 +3602,7 @@ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metad
|
|
|
3424
3602
|
if (type.getProperties().length > 0) {
|
|
3425
3603
|
return null;
|
|
3426
3604
|
}
|
|
3427
|
-
const indexInfo = checker.getIndexInfoOfType(type,
|
|
3605
|
+
const indexInfo = checker.getIndexInfoOfType(type, ts5.IndexKind.String);
|
|
3428
3606
|
if (!indexInfo) {
|
|
3429
3607
|
return null;
|
|
3430
3608
|
}
|
|
@@ -3472,20 +3650,53 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
|
3472
3650
|
}
|
|
3473
3651
|
if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
|
|
3474
3652
|
const name = declaration.name;
|
|
3475
|
-
if (
|
|
3653
|
+
if (ts5.isComputedPropertyName(name) || ts5.isPrivateIdentifier(name)) {
|
|
3476
3654
|
return false;
|
|
3477
3655
|
}
|
|
3478
|
-
if (!
|
|
3656
|
+
if (!ts5.isIdentifier(name) && !ts5.isStringLiteral(name) && !ts5.isNumericLiteral(name)) {
|
|
3479
3657
|
return false;
|
|
3480
3658
|
}
|
|
3481
3659
|
}
|
|
3482
3660
|
return true;
|
|
3483
3661
|
}
|
|
3662
|
+
function getPassThroughTypeAliasFromSourceNode(sourceNode, checker, extensionRegistry, resolvedTypeName) {
|
|
3663
|
+
const aliasDecl = getReferencedTypeAliasDeclaration(sourceNode, checker);
|
|
3664
|
+
if (!aliasDecl) return void 0;
|
|
3665
|
+
const aliasName = aliasDecl.name.text;
|
|
3666
|
+
if (aliasName === resolvedTypeName) return void 0;
|
|
3667
|
+
if (!ts5.isTypeReferenceNode(aliasDecl.type)) return void 0;
|
|
3668
|
+
if (!hasInheritableTypeAnnotation(aliasDecl, checker, extensionRegistry)) {
|
|
3669
|
+
return void 0;
|
|
3670
|
+
}
|
|
3671
|
+
return { aliasName, aliasDecl };
|
|
3672
|
+
}
|
|
3673
|
+
function hasInheritableTypeAnnotation(aliasDecl, checker, extensionRegistry) {
|
|
3674
|
+
const file = aliasDecl.getSourceFile().fileName;
|
|
3675
|
+
const local = extractJSDocAnnotationNodes(aliasDecl, file, makeParseOptions(extensionRegistry));
|
|
3676
|
+
for (const annotation of local) {
|
|
3677
|
+
if (!INHERITABLE_TYPE_ANNOTATION_KINDS.has(annotation.annotationKind)) continue;
|
|
3678
|
+
if (!isOverridingInheritableAnnotation(annotation)) continue;
|
|
3679
|
+
return true;
|
|
3680
|
+
}
|
|
3681
|
+
const inherited = collectInheritedTypeAnnotations(aliasDecl, local, checker, extensionRegistry);
|
|
3682
|
+
for (const annotation of inherited) {
|
|
3683
|
+
if (INHERITABLE_TYPE_ANNOTATION_KINDS.has(annotation.annotationKind)) return true;
|
|
3684
|
+
}
|
|
3685
|
+
return false;
|
|
3686
|
+
}
|
|
3484
3687
|
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3485
3688
|
const collectedDiagnostics = diagnostics ?? [];
|
|
3486
3689
|
const typeName = getNamedTypeName(type);
|
|
3487
3690
|
const namedTypeName = typeName ?? void 0;
|
|
3488
3691
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
3692
|
+
const passThroughAlias = getPassThroughTypeAliasFromSourceNode(
|
|
3693
|
+
sourceNode,
|
|
3694
|
+
checker,
|
|
3695
|
+
extensionRegistry,
|
|
3696
|
+
namedTypeName
|
|
3697
|
+
);
|
|
3698
|
+
const effectiveTypeName = passThroughAlias?.aliasName ?? namedTypeName;
|
|
3699
|
+
const effectiveNamedDecl = passThroughAlias?.aliasDecl ?? namedDecl;
|
|
3489
3700
|
const referenceTypeArguments = extractReferenceTypeArguments(
|
|
3490
3701
|
type,
|
|
3491
3702
|
checker,
|
|
@@ -3497,13 +3708,13 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3497
3708
|
extensionRegistry,
|
|
3498
3709
|
collectedDiagnostics
|
|
3499
3710
|
);
|
|
3500
|
-
const instantiatedTypeName =
|
|
3501
|
-
|
|
3711
|
+
const instantiatedTypeName = effectiveTypeName !== void 0 && referenceTypeArguments.length > 0 ? buildInstantiatedReferenceName(
|
|
3712
|
+
effectiveTypeName,
|
|
3502
3713
|
referenceTypeArguments.map((argument) => argument.tsType),
|
|
3503
3714
|
checker
|
|
3504
3715
|
) : void 0;
|
|
3505
|
-
const registryTypeName = instantiatedTypeName ??
|
|
3506
|
-
const shouldRegisterNamedType = registryTypeName !== void 0 && !(registryTypeName === "Record" &&
|
|
3716
|
+
const registryTypeName = instantiatedTypeName ?? effectiveTypeName;
|
|
3717
|
+
const shouldRegisterNamedType = registryTypeName !== void 0 && !(registryTypeName === "Record" && effectiveNamedDecl?.getSourceFile().fileName !== file);
|
|
3507
3718
|
const clearNamedTypeRegistration = () => {
|
|
3508
3719
|
if (registryTypeName === void 0 || !shouldRegisterNamedType) {
|
|
3509
3720
|
return;
|
|
@@ -3524,7 +3735,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3524
3735
|
typeRegistry[registryTypeName] = {
|
|
3525
3736
|
name: registryTypeName,
|
|
3526
3737
|
type: RESOLVING_TYPE_PLACEHOLDER,
|
|
3527
|
-
provenance: provenanceForDeclaration(
|
|
3738
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
3528
3739
|
};
|
|
3529
3740
|
}
|
|
3530
3741
|
visiting.add(type);
|
|
@@ -3556,17 +3767,17 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3556
3767
|
clearNamedTypeRegistration();
|
|
3557
3768
|
return recordNode;
|
|
3558
3769
|
}
|
|
3559
|
-
const annotations =
|
|
3560
|
-
const metadata =
|
|
3770
|
+
const annotations = effectiveNamedDecl ? extractNamedTypeAnnotations(effectiveNamedDecl, checker, file, extensionRegistry) : void 0;
|
|
3771
|
+
const metadata = effectiveNamedDecl !== void 0 ? resolveNodeMetadata(
|
|
3561
3772
|
metadataPolicy,
|
|
3562
3773
|
"type",
|
|
3563
3774
|
registryTypeName,
|
|
3564
|
-
|
|
3775
|
+
effectiveNamedDecl,
|
|
3565
3776
|
checker,
|
|
3566
3777
|
extensionRegistry,
|
|
3567
3778
|
{
|
|
3568
3779
|
checker,
|
|
3569
|
-
declaration:
|
|
3780
|
+
declaration: effectiveNamedDecl,
|
|
3570
3781
|
subjectType: type
|
|
3571
3782
|
}
|
|
3572
3783
|
) : void 0;
|
|
@@ -3575,7 +3786,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3575
3786
|
...metadata !== void 0 && { metadata },
|
|
3576
3787
|
type: recordNode,
|
|
3577
3788
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
3578
|
-
provenance: provenanceForDeclaration(
|
|
3789
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
3579
3790
|
};
|
|
3580
3791
|
return {
|
|
3581
3792
|
kind: "reference",
|
|
@@ -3601,7 +3812,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3601
3812
|
if (!declaration) continue;
|
|
3602
3813
|
if (!shouldEmitResolvedObjectProperty(prop, declaration)) continue;
|
|
3603
3814
|
const propType = checker.getTypeOfSymbolAtLocation(prop, declaration);
|
|
3604
|
-
const optional = !!(prop.flags &
|
|
3815
|
+
const optional = !!(prop.flags & ts5.SymbolFlags.Optional);
|
|
3605
3816
|
const propTypeNode = resolveTypeNode(
|
|
3606
3817
|
propType,
|
|
3607
3818
|
checker,
|
|
@@ -3614,7 +3825,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3614
3825
|
collectedDiagnostics
|
|
3615
3826
|
);
|
|
3616
3827
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
3617
|
-
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ?
|
|
3828
|
+
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts5.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
|
|
3618
3829
|
declaration,
|
|
3619
3830
|
checker,
|
|
3620
3831
|
file,
|
|
@@ -3624,7 +3835,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3624
3835
|
type,
|
|
3625
3836
|
metadataPolicy,
|
|
3626
3837
|
extensionRegistry
|
|
3627
|
-
) :
|
|
3838
|
+
) : ts5.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
|
|
3628
3839
|
declaration,
|
|
3629
3840
|
checker,
|
|
3630
3841
|
file,
|
|
@@ -3652,9 +3863,9 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3652
3863
|
visiting.delete(type);
|
|
3653
3864
|
const objectNode = {
|
|
3654
3865
|
kind: "object",
|
|
3655
|
-
properties:
|
|
3866
|
+
properties: effectiveNamedDecl !== void 0 && (ts5.isClassDeclaration(effectiveNamedDecl) || ts5.isInterfaceDeclaration(effectiveNamedDecl) || ts5.isTypeAliasDeclaration(effectiveNamedDecl)) ? applyDiscriminatorToObjectProperties(
|
|
3656
3867
|
properties,
|
|
3657
|
-
|
|
3868
|
+
effectiveNamedDecl,
|
|
3658
3869
|
type,
|
|
3659
3870
|
checker,
|
|
3660
3871
|
file,
|
|
@@ -3664,17 +3875,17 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3664
3875
|
additionalProperties: true
|
|
3665
3876
|
};
|
|
3666
3877
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
3667
|
-
const annotations =
|
|
3668
|
-
const metadata =
|
|
3878
|
+
const annotations = effectiveNamedDecl ? extractNamedTypeAnnotations(effectiveNamedDecl, checker, file, extensionRegistry) : void 0;
|
|
3879
|
+
const metadata = effectiveNamedDecl !== void 0 ? resolveNodeMetadata(
|
|
3669
3880
|
metadataPolicy,
|
|
3670
3881
|
"type",
|
|
3671
3882
|
registryTypeName,
|
|
3672
|
-
|
|
3883
|
+
effectiveNamedDecl,
|
|
3673
3884
|
checker,
|
|
3674
3885
|
extensionRegistry,
|
|
3675
3886
|
{
|
|
3676
3887
|
checker,
|
|
3677
|
-
declaration:
|
|
3888
|
+
declaration: effectiveNamedDecl,
|
|
3678
3889
|
subjectType: type
|
|
3679
3890
|
}
|
|
3680
3891
|
) : void 0;
|
|
@@ -3683,7 +3894,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3683
3894
|
...metadata !== void 0 && { metadata },
|
|
3684
3895
|
type: objectNode,
|
|
3685
3896
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
3686
|
-
provenance: provenanceForDeclaration(
|
|
3897
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
3687
3898
|
};
|
|
3688
3899
|
return {
|
|
3689
3900
|
kind: "reference",
|
|
@@ -3700,12 +3911,12 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3700
3911
|
for (const symbol of symbols) {
|
|
3701
3912
|
const declarations = symbol.declarations;
|
|
3702
3913
|
if (!declarations) continue;
|
|
3703
|
-
const classDecl = declarations.find(
|
|
3914
|
+
const classDecl = declarations.find(ts5.isClassDeclaration);
|
|
3704
3915
|
if (classDecl) {
|
|
3705
3916
|
const map = /* @__PURE__ */ new Map();
|
|
3706
3917
|
const hostType = checker.getTypeAtLocation(classDecl);
|
|
3707
3918
|
for (const member of classDecl.members) {
|
|
3708
|
-
if (
|
|
3919
|
+
if (ts5.isPropertyDeclaration(member) && ts5.isIdentifier(member.name)) {
|
|
3709
3920
|
const fieldNode = analyzeFieldToIR(
|
|
3710
3921
|
member,
|
|
3711
3922
|
checker,
|
|
@@ -3729,7 +3940,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3729
3940
|
}
|
|
3730
3941
|
return map;
|
|
3731
3942
|
}
|
|
3732
|
-
const interfaceDecl = declarations.find(
|
|
3943
|
+
const interfaceDecl = declarations.find(ts5.isInterfaceDeclaration);
|
|
3733
3944
|
if (interfaceDecl) {
|
|
3734
3945
|
return buildFieldNodeInfoMap(
|
|
3735
3946
|
interfaceDecl.members,
|
|
@@ -3743,7 +3954,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3743
3954
|
extensionRegistry
|
|
3744
3955
|
);
|
|
3745
3956
|
}
|
|
3746
|
-
const typeAliasDecl = declarations.find(
|
|
3957
|
+
const typeAliasDecl = declarations.find(ts5.isTypeAliasDeclaration);
|
|
3747
3958
|
const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
|
|
3748
3959
|
if (typeAliasDecl && typeAliasMembers !== null) {
|
|
3749
3960
|
return buildFieldNodeInfoMap(
|
|
@@ -3767,10 +3978,10 @@ function extractArrayElementTypeNode(sourceNode, checker) {
|
|
|
3767
3978
|
return void 0;
|
|
3768
3979
|
}
|
|
3769
3980
|
const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
|
|
3770
|
-
if (
|
|
3981
|
+
if (ts5.isArrayTypeNode(resolvedTypeNode)) {
|
|
3771
3982
|
return resolvedTypeNode.elementType;
|
|
3772
3983
|
}
|
|
3773
|
-
if (
|
|
3984
|
+
if (ts5.isTypeReferenceNode(resolvedTypeNode) && ts5.isIdentifier(resolvedTypeNode.typeName) && resolvedTypeNode.typeName.text === "Array" && resolvedTypeNode.typeArguments?.[0]) {
|
|
3774
3985
|
return resolvedTypeNode.typeArguments[0];
|
|
3775
3986
|
}
|
|
3776
3987
|
return void 0;
|
|
@@ -3781,13 +3992,13 @@ function extractUnionMemberTypeNodes(sourceNode, checker) {
|
|
|
3781
3992
|
return [];
|
|
3782
3993
|
}
|
|
3783
3994
|
const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
|
|
3784
|
-
return
|
|
3995
|
+
return ts5.isUnionTypeNode(resolvedTypeNode) ? [...resolvedTypeNode.types] : [];
|
|
3785
3996
|
}
|
|
3786
3997
|
function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new Set()) {
|
|
3787
|
-
if (
|
|
3998
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
3788
3999
|
return resolveAliasedTypeNode(typeNode.type, checker, visited);
|
|
3789
4000
|
}
|
|
3790
|
-
if (!
|
|
4001
|
+
if (!ts5.isTypeReferenceNode(typeNode) || !ts5.isIdentifier(typeNode.typeName)) {
|
|
3791
4002
|
return typeNode;
|
|
3792
4003
|
}
|
|
3793
4004
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -3798,15 +4009,15 @@ function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new
|
|
|
3798
4009
|
return resolveAliasedTypeNode(aliasDecl.type, checker, visited);
|
|
3799
4010
|
}
|
|
3800
4011
|
function isNullishTypeNode(typeNode) {
|
|
3801
|
-
if (typeNode.kind ===
|
|
4012
|
+
if (typeNode.kind === ts5.SyntaxKind.NullKeyword || typeNode.kind === ts5.SyntaxKind.UndefinedKeyword) {
|
|
3802
4013
|
return true;
|
|
3803
4014
|
}
|
|
3804
|
-
return
|
|
4015
|
+
return ts5.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts5.SyntaxKind.NullKeyword || typeNode.literal.kind === ts5.SyntaxKind.UndefinedKeyword);
|
|
3805
4016
|
}
|
|
3806
4017
|
function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, metadataPolicy, hostType, diagnostics, extensionRegistry) {
|
|
3807
4018
|
const map = /* @__PURE__ */ new Map();
|
|
3808
4019
|
for (const member of members) {
|
|
3809
|
-
if (
|
|
4020
|
+
if (ts5.isPropertySignature(member)) {
|
|
3810
4021
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
3811
4022
|
member,
|
|
3812
4023
|
checker,
|
|
@@ -3832,7 +4043,7 @@ function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, m
|
|
|
3832
4043
|
}
|
|
3833
4044
|
var MAX_ALIAS_CHAIN_DEPTH = 8;
|
|
3834
4045
|
function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegistry, depth = 0) {
|
|
3835
|
-
if (!
|
|
4046
|
+
if (!ts5.isTypeReferenceNode(typeNode)) return [];
|
|
3836
4047
|
if (depth >= MAX_ALIAS_CHAIN_DEPTH) {
|
|
3837
4048
|
const aliasName = typeNode.typeName.getText();
|
|
3838
4049
|
throw new Error(
|
|
@@ -3841,7 +4052,7 @@ function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegis
|
|
|
3841
4052
|
}
|
|
3842
4053
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
3843
4054
|
if (!aliasDecl) return [];
|
|
3844
|
-
if (
|
|
4055
|
+
if (ts5.isTypeLiteralNode(aliasDecl.type)) return [];
|
|
3845
4056
|
const aliasFieldType = resolveTypeNode(
|
|
3846
4057
|
checker.getTypeAtLocation(aliasDecl.type),
|
|
3847
4058
|
checker,
|
|
@@ -3885,14 +4096,14 @@ function getNamedTypeName(type) {
|
|
|
3885
4096
|
const symbol = type.getSymbol();
|
|
3886
4097
|
if (symbol?.declarations) {
|
|
3887
4098
|
const decl = symbol.declarations[0];
|
|
3888
|
-
if (decl && (
|
|
3889
|
-
const name =
|
|
4099
|
+
if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
|
|
4100
|
+
const name = ts5.isClassDeclaration(decl) ? decl.name?.text : decl.name.text;
|
|
3890
4101
|
if (name) return name;
|
|
3891
4102
|
}
|
|
3892
4103
|
}
|
|
3893
4104
|
const aliasSymbol = type.aliasSymbol;
|
|
3894
4105
|
if (aliasSymbol?.declarations) {
|
|
3895
|
-
const aliasDecl = aliasSymbol.declarations.find(
|
|
4106
|
+
const aliasDecl = aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
|
|
3896
4107
|
if (aliasDecl) {
|
|
3897
4108
|
return aliasDecl.name.text;
|
|
3898
4109
|
}
|
|
@@ -3903,24 +4114,24 @@ function getNamedTypeDeclaration(type) {
|
|
|
3903
4114
|
const symbol = type.getSymbol();
|
|
3904
4115
|
if (symbol?.declarations) {
|
|
3905
4116
|
const decl = symbol.declarations[0];
|
|
3906
|
-
if (decl && (
|
|
4117
|
+
if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
|
|
3907
4118
|
return decl;
|
|
3908
4119
|
}
|
|
3909
4120
|
}
|
|
3910
4121
|
const aliasSymbol = type.aliasSymbol;
|
|
3911
4122
|
if (aliasSymbol?.declarations) {
|
|
3912
|
-
return aliasSymbol.declarations.find(
|
|
4123
|
+
return aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
|
|
3913
4124
|
}
|
|
3914
4125
|
return void 0;
|
|
3915
4126
|
}
|
|
3916
4127
|
function analyzeMethod(method, checker) {
|
|
3917
|
-
if (!
|
|
4128
|
+
if (!ts5.isIdentifier(method.name)) {
|
|
3918
4129
|
return null;
|
|
3919
4130
|
}
|
|
3920
4131
|
const name = method.name.text;
|
|
3921
4132
|
const parameters = [];
|
|
3922
4133
|
for (const param of method.parameters) {
|
|
3923
|
-
if (
|
|
4134
|
+
if (ts5.isIdentifier(param.name)) {
|
|
3924
4135
|
const paramInfo = analyzeParameter(param, checker);
|
|
3925
4136
|
parameters.push(paramInfo);
|
|
3926
4137
|
}
|
|
@@ -3931,7 +4142,7 @@ function analyzeMethod(method, checker) {
|
|
|
3931
4142
|
return { name, parameters, returnTypeNode, returnType };
|
|
3932
4143
|
}
|
|
3933
4144
|
function analyzeParameter(param, checker) {
|
|
3934
|
-
const name =
|
|
4145
|
+
const name = ts5.isIdentifier(param.name) ? param.name.text : "param";
|
|
3935
4146
|
const typeNode = param.type;
|
|
3936
4147
|
const type = checker.getTypeAtLocation(param);
|
|
3937
4148
|
const formSpecExportName = detectFormSpecReference(typeNode);
|
|
@@ -3940,15 +4151,15 @@ function analyzeParameter(param, checker) {
|
|
|
3940
4151
|
}
|
|
3941
4152
|
function detectFormSpecReference(typeNode) {
|
|
3942
4153
|
if (!typeNode) return null;
|
|
3943
|
-
if (!
|
|
3944
|
-
const typeName =
|
|
4154
|
+
if (!ts5.isTypeReferenceNode(typeNode)) return null;
|
|
4155
|
+
const typeName = ts5.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : ts5.isQualifiedName(typeNode.typeName) ? typeNode.typeName.right.text : null;
|
|
3945
4156
|
if (typeName !== "InferSchema" && typeName !== "InferFormSchema") return null;
|
|
3946
4157
|
const typeArg = typeNode.typeArguments?.[0];
|
|
3947
|
-
if (!typeArg || !
|
|
3948
|
-
if (
|
|
4158
|
+
if (!typeArg || !ts5.isTypeQueryNode(typeArg)) return null;
|
|
4159
|
+
if (ts5.isIdentifier(typeArg.exprName)) {
|
|
3949
4160
|
return typeArg.exprName.text;
|
|
3950
4161
|
}
|
|
3951
|
-
if (
|
|
4162
|
+
if (ts5.isQualifiedName(typeArg.exprName)) {
|
|
3952
4163
|
return typeArg.exprName.right.text;
|
|
3953
4164
|
}
|
|
3954
4165
|
return null;
|
|
@@ -3970,23 +4181,23 @@ function createProgramContextFromProgram(program, filePath) {
|
|
|
3970
4181
|
function createProgramContext(filePath, additionalFiles) {
|
|
3971
4182
|
const absolutePath = path.resolve(filePath);
|
|
3972
4183
|
const fileDir = path.dirname(absolutePath);
|
|
3973
|
-
const configPath =
|
|
4184
|
+
const configPath = ts6.findConfigFile(fileDir, ts6.sys.fileExists.bind(ts6.sys), "tsconfig.json");
|
|
3974
4185
|
let compilerOptions;
|
|
3975
4186
|
let fileNames;
|
|
3976
4187
|
if (configPath) {
|
|
3977
|
-
const configFile =
|
|
4188
|
+
const configFile = ts6.readConfigFile(configPath, ts6.sys.readFile.bind(ts6.sys));
|
|
3978
4189
|
if (configFile.error) {
|
|
3979
4190
|
throw new Error(
|
|
3980
|
-
`Error reading tsconfig.json: ${
|
|
4191
|
+
`Error reading tsconfig.json: ${ts6.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
|
|
3981
4192
|
);
|
|
3982
4193
|
}
|
|
3983
|
-
const parsed =
|
|
4194
|
+
const parsed = ts6.parseJsonConfigFileContent(
|
|
3984
4195
|
configFile.config,
|
|
3985
|
-
|
|
4196
|
+
ts6.sys,
|
|
3986
4197
|
path.dirname(configPath)
|
|
3987
4198
|
);
|
|
3988
4199
|
if (parsed.errors.length > 0) {
|
|
3989
|
-
const errorMessages = parsed.errors.map((e) =>
|
|
4200
|
+
const errorMessages = parsed.errors.map((e) => ts6.flattenDiagnosticMessageText(e.messageText, "\n")).join("\n");
|
|
3990
4201
|
throw new Error(`Error parsing tsconfig.json: ${errorMessages}`);
|
|
3991
4202
|
}
|
|
3992
4203
|
compilerOptions = parsed.options;
|
|
@@ -3994,9 +4205,9 @@ function createProgramContext(filePath, additionalFiles) {
|
|
|
3994
4205
|
fileNames = [.../* @__PURE__ */ new Set([...parsed.fileNames, absolutePath, ...normalizedAdditional])];
|
|
3995
4206
|
} else {
|
|
3996
4207
|
compilerOptions = {
|
|
3997
|
-
target:
|
|
3998
|
-
module:
|
|
3999
|
-
moduleResolution:
|
|
4208
|
+
target: ts6.ScriptTarget.ES2022,
|
|
4209
|
+
module: ts6.ModuleKind.NodeNext,
|
|
4210
|
+
moduleResolution: ts6.ModuleResolutionKind.NodeNext,
|
|
4000
4211
|
strict: true,
|
|
4001
4212
|
skipLibCheck: true,
|
|
4002
4213
|
declaration: true
|
|
@@ -4004,7 +4215,7 @@ function createProgramContext(filePath, additionalFiles) {
|
|
|
4004
4215
|
const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
|
|
4005
4216
|
fileNames = [.../* @__PURE__ */ new Set([absolutePath, ...normalizedAdditional])];
|
|
4006
4217
|
}
|
|
4007
|
-
const program =
|
|
4218
|
+
const program = ts6.createProgram(fileNames, compilerOptions);
|
|
4008
4219
|
const sourceFile = program.getSourceFile(absolutePath);
|
|
4009
4220
|
if (!sourceFile) {
|
|
4010
4221
|
throw new Error(`Could not find source file: ${absolutePath}`);
|
|
@@ -4023,19 +4234,19 @@ function findNodeByName(sourceFile, name, predicate, getName) {
|
|
|
4023
4234
|
result = node;
|
|
4024
4235
|
return;
|
|
4025
4236
|
}
|
|
4026
|
-
|
|
4237
|
+
ts6.forEachChild(node, visit);
|
|
4027
4238
|
}
|
|
4028
4239
|
visit(sourceFile);
|
|
4029
4240
|
return result;
|
|
4030
4241
|
}
|
|
4031
4242
|
function findClassByName(sourceFile, className) {
|
|
4032
|
-
return findNodeByName(sourceFile, className,
|
|
4243
|
+
return findNodeByName(sourceFile, className, ts6.isClassDeclaration, (n) => n.name?.text);
|
|
4033
4244
|
}
|
|
4034
4245
|
function findInterfaceByName(sourceFile, interfaceName) {
|
|
4035
|
-
return findNodeByName(sourceFile, interfaceName,
|
|
4246
|
+
return findNodeByName(sourceFile, interfaceName, ts6.isInterfaceDeclaration, (n) => n.name.text);
|
|
4036
4247
|
}
|
|
4037
4248
|
function findTypeAliasByName(sourceFile, aliasName) {
|
|
4038
|
-
return findNodeByName(sourceFile, aliasName,
|
|
4249
|
+
return findNodeByName(sourceFile, aliasName, ts6.isTypeAliasDeclaration, (n) => n.name.text);
|
|
4039
4250
|
}
|
|
4040
4251
|
function getResolvedObjectRootType(rootType, typeRegistry) {
|
|
4041
4252
|
if (rootType.kind === "object") {
|
|
@@ -4075,22 +4286,22 @@ function createResolvedObjectAliasAnalysis(name, rootType, typeRegistry, rootInf
|
|
|
4075
4286
|
};
|
|
4076
4287
|
}
|
|
4077
4288
|
function containsTypeReferenceInObjectLikeAlias(typeNode) {
|
|
4078
|
-
if (
|
|
4289
|
+
if (ts6.isParenthesizedTypeNode(typeNode)) {
|
|
4079
4290
|
return containsTypeReferenceInObjectLikeAlias(typeNode.type);
|
|
4080
4291
|
}
|
|
4081
|
-
if (
|
|
4292
|
+
if (ts6.isTypeReferenceNode(typeNode)) {
|
|
4082
4293
|
return true;
|
|
4083
4294
|
}
|
|
4084
|
-
return
|
|
4295
|
+
return ts6.isIntersectionTypeNode(typeNode) && typeNode.types.some((member) => containsTypeReferenceInObjectLikeAlias(member));
|
|
4085
4296
|
}
|
|
4086
4297
|
function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
|
|
4087
|
-
if (
|
|
4298
|
+
if (ts6.isParenthesizedTypeNode(typeNode)) {
|
|
4088
4299
|
return collectFallbackAliasMemberPropertyNames(typeNode.type, checker);
|
|
4089
4300
|
}
|
|
4090
|
-
if (
|
|
4301
|
+
if (ts6.isTypeLiteralNode(typeNode)) {
|
|
4091
4302
|
const propertyNames = [];
|
|
4092
4303
|
for (const member of typeNode.members) {
|
|
4093
|
-
if (!
|
|
4304
|
+
if (!ts6.isPropertySignature(member)) {
|
|
4094
4305
|
continue;
|
|
4095
4306
|
}
|
|
4096
4307
|
const propertyName = getAnalyzableObjectLikePropertyName(member.name);
|
|
@@ -4100,13 +4311,13 @@ function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
|
|
|
4100
4311
|
}
|
|
4101
4312
|
return propertyNames;
|
|
4102
4313
|
}
|
|
4103
|
-
if (
|
|
4314
|
+
if (ts6.isTypeReferenceNode(typeNode)) {
|
|
4104
4315
|
return checker.getTypeFromTypeNode(typeNode).getProperties().map((property) => property.getName());
|
|
4105
4316
|
}
|
|
4106
4317
|
return null;
|
|
4107
4318
|
}
|
|
4108
4319
|
function findFallbackAliasDuplicatePropertyNames(typeNode, checker) {
|
|
4109
|
-
if (!
|
|
4320
|
+
if (!ts6.isIntersectionTypeNode(typeNode)) {
|
|
4110
4321
|
return [];
|
|
4111
4322
|
}
|
|
4112
4323
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -4296,7 +4507,7 @@ function makeFileProvenance(filePath) {
|
|
|
4296
4507
|
}
|
|
4297
4508
|
|
|
4298
4509
|
// src/generators/class-schema.ts
|
|
4299
|
-
import * as
|
|
4510
|
+
import * as ts8 from "typescript";
|
|
4300
4511
|
|
|
4301
4512
|
// src/metadata/collision-guards.ts
|
|
4302
4513
|
function assertUniqueSerializedNames(entries, scope) {
|
|
@@ -4465,7 +4676,7 @@ function generateJsonSchemaFromIR(ir, options) {
|
|
|
4465
4676
|
applyConstraints(ctx.defs[schemaName], typeDef.constraints, ctx);
|
|
4466
4677
|
}
|
|
4467
4678
|
if (typeDef.annotations && typeDef.annotations.length > 0) {
|
|
4468
|
-
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx);
|
|
4679
|
+
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx, typeDef.type);
|
|
4469
4680
|
}
|
|
4470
4681
|
}
|
|
4471
4682
|
const properties = {};
|
|
@@ -4538,7 +4749,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
4538
4749
|
}
|
|
4539
4750
|
}
|
|
4540
4751
|
applyResolvedMetadata(schema, field.metadata);
|
|
4541
|
-
applyAnnotations(schema, rootAnnotations, ctx);
|
|
4752
|
+
applyAnnotations(schema, rootAnnotations, ctx, field.type);
|
|
4542
4753
|
if (itemStringSchema !== void 0) {
|
|
4543
4754
|
applyAnnotations(itemStringSchema, itemAnnotations, ctx);
|
|
4544
4755
|
}
|
|
@@ -4581,32 +4792,36 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
4581
4792
|
return schema;
|
|
4582
4793
|
}
|
|
4583
4794
|
if (schema.$ref) {
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
properties: propertyOverrides,
|
|
4588
|
-
...rest
|
|
4795
|
+
return {
|
|
4796
|
+
...schema,
|
|
4797
|
+
properties: propertyOverrides
|
|
4589
4798
|
};
|
|
4590
|
-
return { allOf: [refPart, overridePart] };
|
|
4591
4799
|
}
|
|
4592
4800
|
if (schema.type === "object" && schema.properties) {
|
|
4593
|
-
const missingOverrides = {};
|
|
4594
4801
|
for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
|
|
4595
|
-
if (schema.properties
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4802
|
+
if (Object.hasOwn(schema.properties, target)) {
|
|
4803
|
+
const existing = schema.properties[target];
|
|
4804
|
+
if (existing) {
|
|
4805
|
+
mergeSchemaOverride(existing, overrideSchema);
|
|
4806
|
+
continue;
|
|
4807
|
+
}
|
|
4599
4808
|
}
|
|
4809
|
+
Object.defineProperty(schema.properties, target, {
|
|
4810
|
+
value: overrideSchema,
|
|
4811
|
+
writable: true,
|
|
4812
|
+
enumerable: true,
|
|
4813
|
+
configurable: true
|
|
4814
|
+
});
|
|
4600
4815
|
}
|
|
4601
|
-
|
|
4602
|
-
return schema;
|
|
4603
|
-
}
|
|
4604
|
-
return {
|
|
4605
|
-
allOf: [schema, { properties: missingOverrides }]
|
|
4606
|
-
};
|
|
4816
|
+
return schema;
|
|
4607
4817
|
}
|
|
4608
4818
|
if (schema.allOf) {
|
|
4609
|
-
|
|
4819
|
+
const overrideMember = { properties: propertyOverrides };
|
|
4820
|
+
const flattened = tryFlattenAllOfToSiblings(schema, overrideMember);
|
|
4821
|
+
if (flattened !== void 0) {
|
|
4822
|
+
return flattened;
|
|
4823
|
+
}
|
|
4824
|
+
schema.allOf = [...schema.allOf, overrideMember];
|
|
4610
4825
|
return schema;
|
|
4611
4826
|
}
|
|
4612
4827
|
return schema;
|
|
@@ -4719,7 +4934,7 @@ function generatePropertySchema(prop, ctx) {
|
|
|
4719
4934
|
const schema = generateTypeNode(prop.type, ctx);
|
|
4720
4935
|
applyConstraints(schema, prop.constraints, ctx);
|
|
4721
4936
|
applyResolvedMetadata(schema, prop.metadata);
|
|
4722
|
-
applyAnnotations(schema, prop.annotations, ctx);
|
|
4937
|
+
applyAnnotations(schema, prop.annotations, ctx, prop.type);
|
|
4723
4938
|
return schema;
|
|
4724
4939
|
}
|
|
4725
4940
|
function generateUnionType(type, ctx) {
|
|
@@ -4822,13 +5037,20 @@ function buildPropertyOverrides(pathConstraints, typeNode, ctx) {
|
|
|
4822
5037
|
grouped.push(constraint);
|
|
4823
5038
|
byTarget.set(target, grouped);
|
|
4824
5039
|
}
|
|
4825
|
-
const overrides =
|
|
5040
|
+
const overrides = /* @__PURE__ */ Object.create(null);
|
|
4826
5041
|
for (const [target, constraints] of byTarget) {
|
|
4827
|
-
|
|
5042
|
+
const resolvedName = resolveSerializedPropertyName(target, typeNode, ctx);
|
|
5043
|
+
const schema = buildPathOverrideSchema(
|
|
4828
5044
|
constraints.map(stripLeadingPathSegment),
|
|
4829
5045
|
resolveTargetTypeNode(target, typeNode, ctx),
|
|
4830
5046
|
ctx
|
|
4831
5047
|
);
|
|
5048
|
+
Object.defineProperty(overrides, resolvedName, {
|
|
5049
|
+
value: schema,
|
|
5050
|
+
writable: true,
|
|
5051
|
+
enumerable: true,
|
|
5052
|
+
configurable: true
|
|
5053
|
+
});
|
|
4832
5054
|
}
|
|
4833
5055
|
return overrides;
|
|
4834
5056
|
}
|
|
@@ -4855,6 +5077,34 @@ function buildPathOverrideSchema(constraints, typeNode, ctx) {
|
|
|
4855
5077
|
schema.properties = buildPropertyOverrides(nestedConstraints, effectiveType, ctx);
|
|
4856
5078
|
return schema;
|
|
4857
5079
|
}
|
|
5080
|
+
function tryFlattenAllOfToSiblings(schema, overrideMember) {
|
|
5081
|
+
if (schema.allOf?.length !== 1) {
|
|
5082
|
+
return void 0;
|
|
5083
|
+
}
|
|
5084
|
+
const [soleMember] = schema.allOf;
|
|
5085
|
+
if (soleMember === void 0) {
|
|
5086
|
+
return void 0;
|
|
5087
|
+
}
|
|
5088
|
+
const { allOf: _allOf, ...outerRest } = schema;
|
|
5089
|
+
const outerKeys = new Set(Object.keys(outerRest));
|
|
5090
|
+
const memberKeys = new Set(Object.keys(soleMember));
|
|
5091
|
+
const overrideKeys = new Set(Object.keys(overrideMember));
|
|
5092
|
+
for (const key of memberKeys) {
|
|
5093
|
+
if (outerKeys.has(key) || overrideKeys.has(key)) {
|
|
5094
|
+
return void 0;
|
|
5095
|
+
}
|
|
5096
|
+
}
|
|
5097
|
+
for (const key of overrideKeys) {
|
|
5098
|
+
if (outerKeys.has(key)) {
|
|
5099
|
+
return void 0;
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
return {
|
|
5103
|
+
...outerRest,
|
|
5104
|
+
...soleMember,
|
|
5105
|
+
...overrideMember
|
|
5106
|
+
};
|
|
5107
|
+
}
|
|
4858
5108
|
function mergeSchemaOverride(target, override) {
|
|
4859
5109
|
const nullableValueBranch = getNullableUnionValueSchema(target);
|
|
4860
5110
|
if (nullableValueBranch !== void 0) {
|
|
@@ -4862,11 +5112,16 @@ function mergeSchemaOverride(target, override) {
|
|
|
4862
5112
|
return;
|
|
4863
5113
|
}
|
|
4864
5114
|
if (override.properties !== void 0) {
|
|
4865
|
-
const mergedProperties = target.properties ??
|
|
5115
|
+
const mergedProperties = target.properties ?? /* @__PURE__ */ Object.create(null);
|
|
4866
5116
|
for (const [name, propertyOverride] of Object.entries(override.properties)) {
|
|
4867
|
-
const existing = mergedProperties[name];
|
|
5117
|
+
const existing = Object.hasOwn(mergedProperties, name) ? mergedProperties[name] : void 0;
|
|
4868
5118
|
if (existing === void 0) {
|
|
4869
|
-
mergedProperties
|
|
5119
|
+
Object.defineProperty(mergedProperties, name, {
|
|
5120
|
+
value: propertyOverride,
|
|
5121
|
+
writable: true,
|
|
5122
|
+
enumerable: true,
|
|
5123
|
+
configurable: true
|
|
5124
|
+
});
|
|
4870
5125
|
} else {
|
|
4871
5126
|
mergeSchemaOverride(existing, propertyOverride);
|
|
4872
5127
|
}
|
|
@@ -4884,7 +5139,12 @@ function mergeSchemaOverride(target, override) {
|
|
|
4884
5139
|
if (key === "properties" || key === "items") {
|
|
4885
5140
|
continue;
|
|
4886
5141
|
}
|
|
4887
|
-
target
|
|
5142
|
+
Object.defineProperty(target, key, {
|
|
5143
|
+
value,
|
|
5144
|
+
writable: true,
|
|
5145
|
+
enumerable: true,
|
|
5146
|
+
configurable: true
|
|
5147
|
+
});
|
|
4888
5148
|
}
|
|
4889
5149
|
}
|
|
4890
5150
|
function stripLeadingPathSegment(constraint) {
|
|
@@ -4984,7 +5244,7 @@ function applyConstraints(schema, constraints, ctx) {
|
|
|
4984
5244
|
}
|
|
4985
5245
|
}
|
|
4986
5246
|
}
|
|
4987
|
-
function applyAnnotations(schema, annotations, ctx) {
|
|
5247
|
+
function applyAnnotations(schema, annotations, ctx, typeNode) {
|
|
4988
5248
|
for (const annotation of annotations) {
|
|
4989
5249
|
switch (annotation.annotationKind) {
|
|
4990
5250
|
case "displayName":
|
|
@@ -4997,7 +5257,7 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
4997
5257
|
schema[`${ctx.vendorPrefix}-remarks`] = annotation.value;
|
|
4998
5258
|
break;
|
|
4999
5259
|
case "defaultValue":
|
|
5000
|
-
schema.default = annotation.value;
|
|
5260
|
+
schema.default = coerceDefaultValue(annotation.value, typeNode, schema, ctx);
|
|
5001
5261
|
break;
|
|
5002
5262
|
case "format":
|
|
5003
5263
|
schema.format = annotation.value;
|
|
@@ -5022,6 +5282,34 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
5022
5282
|
}
|
|
5023
5283
|
}
|
|
5024
5284
|
}
|
|
5285
|
+
function coerceDefaultValue(value, typeNode, emittedSchema, ctx) {
|
|
5286
|
+
if (typeNode?.kind !== "custom") {
|
|
5287
|
+
return value;
|
|
5288
|
+
}
|
|
5289
|
+
const registration = ctx.extensionRegistry?.findType(typeNode.typeId);
|
|
5290
|
+
if (registration === void 0) {
|
|
5291
|
+
return value;
|
|
5292
|
+
}
|
|
5293
|
+
if (registration.serializeDefault !== void 0) {
|
|
5294
|
+
return registration.serializeDefault(value, typeNode.payload);
|
|
5295
|
+
}
|
|
5296
|
+
const declaredType = emittedSchema["type"];
|
|
5297
|
+
if (declaredType === "string" && typeof value !== "string") {
|
|
5298
|
+
if (typeof value === "number") {
|
|
5299
|
+
if (!Number.isFinite(value)) {
|
|
5300
|
+
return value;
|
|
5301
|
+
}
|
|
5302
|
+
return String(value);
|
|
5303
|
+
}
|
|
5304
|
+
if (typeof value === "boolean") {
|
|
5305
|
+
return String(value);
|
|
5306
|
+
}
|
|
5307
|
+
if (typeof value === "bigint") {
|
|
5308
|
+
return value.toString();
|
|
5309
|
+
}
|
|
5310
|
+
}
|
|
5311
|
+
return value;
|
|
5312
|
+
}
|
|
5025
5313
|
function generateCustomType(type, ctx) {
|
|
5026
5314
|
const registration = ctx.extensionRegistry?.findType(type.typeId);
|
|
5027
5315
|
if (registration === void 0) {
|
|
@@ -5154,7 +5442,9 @@ import {
|
|
|
5154
5442
|
import {
|
|
5155
5443
|
getTagDefinition as getTagDefinition2,
|
|
5156
5444
|
normalizeFormSpecTagName as normalizeFormSpecTagName2,
|
|
5157
|
-
getSyntheticLogger as getSyntheticLogger2
|
|
5445
|
+
getSyntheticLogger as getSyntheticLogger2,
|
|
5446
|
+
_validateExtensionSetup,
|
|
5447
|
+
logSetupDiagnostics
|
|
5158
5448
|
} from "@formspec/analysis/internal";
|
|
5159
5449
|
var BUILTIN_METADATA_TAGS = /* @__PURE__ */ new Set(["apiName", "displayName"]);
|
|
5160
5450
|
function buildConstraintTagSources(extensions) {
|
|
@@ -5164,6 +5454,16 @@ function buildConstraintTagSources(extensions) {
|
|
|
5164
5454
|
constraintTags: extension.constraintTags.map((tag) => ({
|
|
5165
5455
|
tagName: normalizeFormSpecTagName2(tag.tagName)
|
|
5166
5456
|
}))
|
|
5457
|
+
} : {},
|
|
5458
|
+
// Include customTypes so _validateExtensionSetup can check tsTypeNames for
|
|
5459
|
+
// unsupported built-in overrides and invalid identifier patterns.
|
|
5460
|
+
...extension.types !== void 0 ? {
|
|
5461
|
+
customTypes: extension.types.map((type) => ({
|
|
5462
|
+
// tsTypeNames: deprecated in favour of symbol-based detection, but
|
|
5463
|
+
// still required for name-based validation in _validateExtensionSetup
|
|
5464
|
+
// until the bridge is fully retired (see §synthetic-checker-retirement §4C).
|
|
5465
|
+
tsTypeNames: type.tsTypeNames ?? [type.typeName]
|
|
5466
|
+
}))
|
|
5167
5467
|
} : {}
|
|
5168
5468
|
}));
|
|
5169
5469
|
}
|
|
@@ -5173,7 +5473,13 @@ function createExtensionRegistry(extensions) {
|
|
|
5173
5473
|
extensionCount: extensions.length,
|
|
5174
5474
|
extensionIds: extensions.map((e) => e.extensionId)
|
|
5175
5475
|
});
|
|
5176
|
-
const
|
|
5476
|
+
const extensionTagSources = buildConstraintTagSources(extensions);
|
|
5477
|
+
const setupDiagnostics = _validateExtensionSetup(extensionTagSources);
|
|
5478
|
+
logSetupDiagnostics(registryLog, {
|
|
5479
|
+
diagnosticCount: setupDiagnostics.length,
|
|
5480
|
+
codes: setupDiagnostics.map((d) => d.kind)
|
|
5481
|
+
});
|
|
5482
|
+
const reservedTagSources = extensionTagSources;
|
|
5177
5483
|
let symbolMap = /* @__PURE__ */ new Map();
|
|
5178
5484
|
const typeMap = /* @__PURE__ */ new Map();
|
|
5179
5485
|
const typeNameMap = /* @__PURE__ */ new Map();
|
|
@@ -5310,10 +5616,12 @@ function createExtensionRegistry(extensions) {
|
|
|
5310
5616
|
constraintTagCount: constraintTagMap.size,
|
|
5311
5617
|
broadeningCount: builtinBroadeningMap.size,
|
|
5312
5618
|
annotationCount: annotationMap.size,
|
|
5313
|
-
metadataSlotCount: metadataSlotMap.size
|
|
5619
|
+
metadataSlotCount: metadataSlotMap.size,
|
|
5620
|
+
setupDiagnosticCount: setupDiagnostics.length
|
|
5314
5621
|
});
|
|
5315
5622
|
return {
|
|
5316
5623
|
extensions,
|
|
5624
|
+
setupDiagnostics,
|
|
5317
5625
|
findType: (typeId) => typeMap.get(typeId),
|
|
5318
5626
|
findTypeByName: (typeName) => typeNameMap.get(typeName),
|
|
5319
5627
|
findTypeByBrand: (brand) => brandMap.get(brand),
|
|
@@ -5329,7 +5637,7 @@ function createExtensionRegistry(extensions) {
|
|
|
5329
5637
|
}
|
|
5330
5638
|
|
|
5331
5639
|
// src/extensions/symbol-registry.ts
|
|
5332
|
-
import * as
|
|
5640
|
+
import * as ts7 from "typescript";
|
|
5333
5641
|
import * as path2 from "path";
|
|
5334
5642
|
|
|
5335
5643
|
// src/ui-schema/schema.ts
|
|
@@ -5722,7 +6030,7 @@ function formatLocation(location) {
|
|
|
5722
6030
|
}
|
|
5723
6031
|
function resolveStaticOptions(options) {
|
|
5724
6032
|
const legacyRegistry = options.extensionRegistry;
|
|
5725
|
-
const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6033
|
+
const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 && options.config.extensions.length > 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
5726
6034
|
return {
|
|
5727
6035
|
extensionRegistry: legacyRegistry ?? configRegistry,
|
|
5728
6036
|
// eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
|