@formspec/build 0.1.0-alpha.58 → 0.1.0-alpha.61
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 +30 -1
- package/dist/analyzer/class-analyzer.d.ts.map +1 -1
- package/dist/analyzer/jsdoc-constraints.d.ts +0 -6
- package/dist/analyzer/jsdoc-constraints.d.ts.map +1 -1
- package/dist/analyzer/tsdoc-parser.d.ts +2 -5
- package/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
- package/dist/browser.cjs +127 -32
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +130 -33
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +432 -12
- package/dist/build-beta.d.ts +400 -12
- package/dist/build-internal.d.ts +463 -12
- package/dist/build.d.ts +400 -12
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts +2 -1
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts.map +1 -1
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts +2 -1
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts.map +1 -1
- package/dist/cli.cjs +610 -629
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +573 -586
- 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/generators/method-schema.d.ts +3 -2
- package/dist/generators/method-schema.d.ts.map +1 -1
- package/dist/index.cjs +600 -618
- 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 +571 -583
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +573 -591
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +540 -552
- package/dist/internals.js.map +1 -1
- package/dist/metadata/index.d.ts +1 -4
- package/dist/metadata/index.d.ts.map +1 -1
- package/dist/metadata/policy.d.ts +2 -6
- package/dist/metadata/policy.d.ts.map +1 -1
- package/dist/metadata/resolve.d.ts +3 -2
- package/dist/metadata/resolve.d.ts.map +1 -1
- package/dist/ui-schema/schema.d.ts +11 -28
- package/dist/ui-schema/schema.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -996,7 +996,7 @@ function generateJsonSchemaFromIR(ir, options) {
|
|
|
996
996
|
applyConstraints(ctx.defs[schemaName], typeDef.constraints, ctx);
|
|
997
997
|
}
|
|
998
998
|
if (typeDef.annotations && typeDef.annotations.length > 0) {
|
|
999
|
-
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx);
|
|
999
|
+
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx, typeDef.type);
|
|
1000
1000
|
}
|
|
1001
1001
|
}
|
|
1002
1002
|
const properties = {};
|
|
@@ -1069,7 +1069,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
1069
1069
|
}
|
|
1070
1070
|
}
|
|
1071
1071
|
applyResolvedMetadata(schema, field.metadata);
|
|
1072
|
-
applyAnnotations(schema, rootAnnotations, ctx);
|
|
1072
|
+
applyAnnotations(schema, rootAnnotations, ctx, field.type);
|
|
1073
1073
|
if (itemStringSchema !== void 0) {
|
|
1074
1074
|
applyAnnotations(itemStringSchema, itemAnnotations, ctx);
|
|
1075
1075
|
}
|
|
@@ -1112,32 +1112,36 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
1112
1112
|
return schema;
|
|
1113
1113
|
}
|
|
1114
1114
|
if (schema.$ref) {
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
properties: propertyOverrides,
|
|
1119
|
-
...rest
|
|
1115
|
+
return {
|
|
1116
|
+
...schema,
|
|
1117
|
+
properties: propertyOverrides
|
|
1120
1118
|
};
|
|
1121
|
-
return { allOf: [refPart, overridePart] };
|
|
1122
1119
|
}
|
|
1123
1120
|
if (schema.type === "object" && schema.properties) {
|
|
1124
|
-
const missingOverrides = {};
|
|
1125
1121
|
for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
|
|
1126
|
-
if (schema.properties
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1122
|
+
if (Object.hasOwn(schema.properties, target)) {
|
|
1123
|
+
const existing = schema.properties[target];
|
|
1124
|
+
if (existing) {
|
|
1125
|
+
mergeSchemaOverride(existing, overrideSchema);
|
|
1126
|
+
continue;
|
|
1127
|
+
}
|
|
1130
1128
|
}
|
|
1129
|
+
Object.defineProperty(schema.properties, target, {
|
|
1130
|
+
value: overrideSchema,
|
|
1131
|
+
writable: true,
|
|
1132
|
+
enumerable: true,
|
|
1133
|
+
configurable: true
|
|
1134
|
+
});
|
|
1131
1135
|
}
|
|
1132
|
-
|
|
1133
|
-
return schema;
|
|
1134
|
-
}
|
|
1135
|
-
return {
|
|
1136
|
-
allOf: [schema, { properties: missingOverrides }]
|
|
1137
|
-
};
|
|
1136
|
+
return schema;
|
|
1138
1137
|
}
|
|
1139
1138
|
if (schema.allOf) {
|
|
1140
|
-
|
|
1139
|
+
const overrideMember = { properties: propertyOverrides };
|
|
1140
|
+
const flattened = tryFlattenAllOfToSiblings(schema, overrideMember);
|
|
1141
|
+
if (flattened !== void 0) {
|
|
1142
|
+
return flattened;
|
|
1143
|
+
}
|
|
1144
|
+
schema.allOf = [...schema.allOf, overrideMember];
|
|
1141
1145
|
return schema;
|
|
1142
1146
|
}
|
|
1143
1147
|
return schema;
|
|
@@ -1250,7 +1254,7 @@ function generatePropertySchema(prop, ctx) {
|
|
|
1250
1254
|
const schema = generateTypeNode(prop.type, ctx);
|
|
1251
1255
|
applyConstraints(schema, prop.constraints, ctx);
|
|
1252
1256
|
applyResolvedMetadata(schema, prop.metadata);
|
|
1253
|
-
applyAnnotations(schema, prop.annotations, ctx);
|
|
1257
|
+
applyAnnotations(schema, prop.annotations, ctx, prop.type);
|
|
1254
1258
|
return schema;
|
|
1255
1259
|
}
|
|
1256
1260
|
function generateUnionType(type, ctx) {
|
|
@@ -1353,13 +1357,20 @@ function buildPropertyOverrides(pathConstraints, typeNode, ctx) {
|
|
|
1353
1357
|
grouped.push(constraint);
|
|
1354
1358
|
byTarget.set(target, grouped);
|
|
1355
1359
|
}
|
|
1356
|
-
const overrides =
|
|
1360
|
+
const overrides = /* @__PURE__ */ Object.create(null);
|
|
1357
1361
|
for (const [target, constraints] of byTarget) {
|
|
1358
|
-
|
|
1362
|
+
const resolvedName = resolveSerializedPropertyName(target, typeNode, ctx);
|
|
1363
|
+
const schema = buildPathOverrideSchema(
|
|
1359
1364
|
constraints.map(stripLeadingPathSegment),
|
|
1360
1365
|
resolveTargetTypeNode(target, typeNode, ctx),
|
|
1361
1366
|
ctx
|
|
1362
1367
|
);
|
|
1368
|
+
Object.defineProperty(overrides, resolvedName, {
|
|
1369
|
+
value: schema,
|
|
1370
|
+
writable: true,
|
|
1371
|
+
enumerable: true,
|
|
1372
|
+
configurable: true
|
|
1373
|
+
});
|
|
1363
1374
|
}
|
|
1364
1375
|
return overrides;
|
|
1365
1376
|
}
|
|
@@ -1386,6 +1397,34 @@ function buildPathOverrideSchema(constraints, typeNode, ctx) {
|
|
|
1386
1397
|
schema.properties = buildPropertyOverrides(nestedConstraints, effectiveType, ctx);
|
|
1387
1398
|
return schema;
|
|
1388
1399
|
}
|
|
1400
|
+
function tryFlattenAllOfToSiblings(schema, overrideMember) {
|
|
1401
|
+
if (schema.allOf?.length !== 1) {
|
|
1402
|
+
return void 0;
|
|
1403
|
+
}
|
|
1404
|
+
const [soleMember] = schema.allOf;
|
|
1405
|
+
if (soleMember === void 0) {
|
|
1406
|
+
return void 0;
|
|
1407
|
+
}
|
|
1408
|
+
const { allOf: _allOf, ...outerRest } = schema;
|
|
1409
|
+
const outerKeys = new Set(Object.keys(outerRest));
|
|
1410
|
+
const memberKeys = new Set(Object.keys(soleMember));
|
|
1411
|
+
const overrideKeys = new Set(Object.keys(overrideMember));
|
|
1412
|
+
for (const key of memberKeys) {
|
|
1413
|
+
if (outerKeys.has(key) || overrideKeys.has(key)) {
|
|
1414
|
+
return void 0;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
for (const key of overrideKeys) {
|
|
1418
|
+
if (outerKeys.has(key)) {
|
|
1419
|
+
return void 0;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
return {
|
|
1423
|
+
...outerRest,
|
|
1424
|
+
...soleMember,
|
|
1425
|
+
...overrideMember
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1389
1428
|
function mergeSchemaOverride(target, override) {
|
|
1390
1429
|
const nullableValueBranch = getNullableUnionValueSchema(target);
|
|
1391
1430
|
if (nullableValueBranch !== void 0) {
|
|
@@ -1393,11 +1432,16 @@ function mergeSchemaOverride(target, override) {
|
|
|
1393
1432
|
return;
|
|
1394
1433
|
}
|
|
1395
1434
|
if (override.properties !== void 0) {
|
|
1396
|
-
const mergedProperties = target.properties ??
|
|
1435
|
+
const mergedProperties = target.properties ?? /* @__PURE__ */ Object.create(null);
|
|
1397
1436
|
for (const [name, propertyOverride] of Object.entries(override.properties)) {
|
|
1398
|
-
const existing = mergedProperties[name];
|
|
1437
|
+
const existing = Object.hasOwn(mergedProperties, name) ? mergedProperties[name] : void 0;
|
|
1399
1438
|
if (existing === void 0) {
|
|
1400
|
-
mergedProperties
|
|
1439
|
+
Object.defineProperty(mergedProperties, name, {
|
|
1440
|
+
value: propertyOverride,
|
|
1441
|
+
writable: true,
|
|
1442
|
+
enumerable: true,
|
|
1443
|
+
configurable: true
|
|
1444
|
+
});
|
|
1401
1445
|
} else {
|
|
1402
1446
|
mergeSchemaOverride(existing, propertyOverride);
|
|
1403
1447
|
}
|
|
@@ -1415,7 +1459,12 @@ function mergeSchemaOverride(target, override) {
|
|
|
1415
1459
|
if (key === "properties" || key === "items") {
|
|
1416
1460
|
continue;
|
|
1417
1461
|
}
|
|
1418
|
-
target
|
|
1462
|
+
Object.defineProperty(target, key, {
|
|
1463
|
+
value,
|
|
1464
|
+
writable: true,
|
|
1465
|
+
enumerable: true,
|
|
1466
|
+
configurable: true
|
|
1467
|
+
});
|
|
1419
1468
|
}
|
|
1420
1469
|
}
|
|
1421
1470
|
function stripLeadingPathSegment(constraint) {
|
|
@@ -1515,7 +1564,7 @@ function applyConstraints(schema, constraints, ctx) {
|
|
|
1515
1564
|
}
|
|
1516
1565
|
}
|
|
1517
1566
|
}
|
|
1518
|
-
function applyAnnotations(schema, annotations, ctx) {
|
|
1567
|
+
function applyAnnotations(schema, annotations, ctx, typeNode) {
|
|
1519
1568
|
for (const annotation of annotations) {
|
|
1520
1569
|
switch (annotation.annotationKind) {
|
|
1521
1570
|
case "displayName":
|
|
@@ -1528,7 +1577,7 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
1528
1577
|
schema[`${ctx.vendorPrefix}-remarks`] = annotation.value;
|
|
1529
1578
|
break;
|
|
1530
1579
|
case "defaultValue":
|
|
1531
|
-
schema.default = annotation.value;
|
|
1580
|
+
schema.default = coerceDefaultValue(annotation.value, typeNode, schema, ctx);
|
|
1532
1581
|
break;
|
|
1533
1582
|
case "format":
|
|
1534
1583
|
schema.format = annotation.value;
|
|
@@ -1553,6 +1602,34 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
1553
1602
|
}
|
|
1554
1603
|
}
|
|
1555
1604
|
}
|
|
1605
|
+
function coerceDefaultValue(value, typeNode, emittedSchema, ctx) {
|
|
1606
|
+
if (typeNode?.kind !== "custom") {
|
|
1607
|
+
return value;
|
|
1608
|
+
}
|
|
1609
|
+
const registration = ctx.extensionRegistry?.findType(typeNode.typeId);
|
|
1610
|
+
if (registration === void 0) {
|
|
1611
|
+
return value;
|
|
1612
|
+
}
|
|
1613
|
+
if (registration.serializeDefault !== void 0) {
|
|
1614
|
+
return registration.serializeDefault(value, typeNode.payload);
|
|
1615
|
+
}
|
|
1616
|
+
const declaredType = emittedSchema["type"];
|
|
1617
|
+
if (declaredType === "string" && typeof value !== "string") {
|
|
1618
|
+
if (typeof value === "number") {
|
|
1619
|
+
if (!Number.isFinite(value)) {
|
|
1620
|
+
return value;
|
|
1621
|
+
}
|
|
1622
|
+
return String(value);
|
|
1623
|
+
}
|
|
1624
|
+
if (typeof value === "boolean") {
|
|
1625
|
+
return String(value);
|
|
1626
|
+
}
|
|
1627
|
+
if (typeof value === "bigint") {
|
|
1628
|
+
return value.toString();
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
return value;
|
|
1632
|
+
}
|
|
1556
1633
|
function generateCustomType(type, ctx) {
|
|
1557
1634
|
const registration = ctx.extensionRegistry?.findType(type.typeId);
|
|
1558
1635
|
if (registration === void 0) {
|
|
@@ -1979,7 +2056,9 @@ import {
|
|
|
1979
2056
|
import {
|
|
1980
2057
|
getTagDefinition,
|
|
1981
2058
|
normalizeFormSpecTagName,
|
|
1982
|
-
|
|
2059
|
+
getRegistryLogger,
|
|
2060
|
+
_validateExtensionSetup,
|
|
2061
|
+
logSetupDiagnostics
|
|
1983
2062
|
} from "@formspec/analysis/internal";
|
|
1984
2063
|
var BUILTIN_METADATA_TAGS = /* @__PURE__ */ new Set(["apiName", "displayName"]);
|
|
1985
2064
|
function buildConstraintTagSources(extensions) {
|
|
@@ -1989,16 +2068,32 @@ function buildConstraintTagSources(extensions) {
|
|
|
1989
2068
|
constraintTags: extension.constraintTags.map((tag) => ({
|
|
1990
2069
|
tagName: normalizeFormSpecTagName(tag.tagName)
|
|
1991
2070
|
}))
|
|
2071
|
+
} : {},
|
|
2072
|
+
// Include customTypes so _validateExtensionSetup can check tsTypeNames for
|
|
2073
|
+
// unsupported built-in overrides and invalid identifier patterns.
|
|
2074
|
+
...extension.types !== void 0 ? {
|
|
2075
|
+
customTypes: extension.types.map((type) => ({
|
|
2076
|
+
// tsTypeNames: deprecated in favour of symbol-based detection, but
|
|
2077
|
+
// still required for name-based validation in _validateExtensionSetup
|
|
2078
|
+
// until the bridge is fully retired (see §synthetic-checker-retirement §4C).
|
|
2079
|
+
tsTypeNames: type.tsTypeNames ?? [type.typeName]
|
|
2080
|
+
}))
|
|
1992
2081
|
} : {}
|
|
1993
2082
|
}));
|
|
1994
2083
|
}
|
|
1995
2084
|
function createExtensionRegistry(extensions) {
|
|
1996
|
-
const registryLog =
|
|
2085
|
+
const registryLog = getRegistryLogger();
|
|
1997
2086
|
registryLog.debug("createExtensionRegistry: constructing", {
|
|
1998
2087
|
extensionCount: extensions.length,
|
|
1999
2088
|
extensionIds: extensions.map((e) => e.extensionId)
|
|
2000
2089
|
});
|
|
2001
|
-
const
|
|
2090
|
+
const extensionTagSources = buildConstraintTagSources(extensions);
|
|
2091
|
+
const setupDiagnostics = _validateExtensionSetup(extensionTagSources);
|
|
2092
|
+
logSetupDiagnostics(registryLog, {
|
|
2093
|
+
diagnosticCount: setupDiagnostics.length,
|
|
2094
|
+
codes: setupDiagnostics.map((d) => d.kind)
|
|
2095
|
+
});
|
|
2096
|
+
const reservedTagSources = extensionTagSources;
|
|
2002
2097
|
let symbolMap = /* @__PURE__ */ new Map();
|
|
2003
2098
|
const typeMap = /* @__PURE__ */ new Map();
|
|
2004
2099
|
const typeNameMap = /* @__PURE__ */ new Map();
|
|
@@ -2135,10 +2230,12 @@ function createExtensionRegistry(extensions) {
|
|
|
2135
2230
|
constraintTagCount: constraintTagMap.size,
|
|
2136
2231
|
broadeningCount: builtinBroadeningMap.size,
|
|
2137
2232
|
annotationCount: annotationMap.size,
|
|
2138
|
-
metadataSlotCount: metadataSlotMap.size
|
|
2233
|
+
metadataSlotCount: metadataSlotMap.size,
|
|
2234
|
+
setupDiagnosticCount: setupDiagnostics.length
|
|
2139
2235
|
});
|
|
2140
2236
|
return {
|
|
2141
2237
|
extensions,
|
|
2238
|
+
setupDiagnostics,
|
|
2142
2239
|
findType: (typeId) => typeMap.get(typeId),
|
|
2143
2240
|
findTypeByName: (typeName) => typeNameMap.get(typeName),
|
|
2144
2241
|
findTypeByBrand: (brand) => brandMap.get(brand),
|
|
@@ -2216,28 +2313,30 @@ var jsonSchema7Schema = z3.lazy(
|
|
|
2216
2313
|
);
|
|
2217
2314
|
|
|
2218
2315
|
// src/generators/class-schema.ts
|
|
2219
|
-
import * as
|
|
2316
|
+
import * as ts8 from "typescript";
|
|
2220
2317
|
|
|
2221
2318
|
// src/analyzer/program.ts
|
|
2222
|
-
import * as
|
|
2319
|
+
import * as ts6 from "typescript";
|
|
2223
2320
|
import * as path from "path";
|
|
2224
2321
|
|
|
2225
2322
|
// src/analyzer/class-analyzer.ts
|
|
2226
|
-
import * as
|
|
2323
|
+
import * as ts5 from "typescript";
|
|
2227
2324
|
import {
|
|
2228
2325
|
analyzeMetadataForNodeWithChecker,
|
|
2229
2326
|
parseCommentBlock
|
|
2230
2327
|
} from "@formspec/analysis/internal";
|
|
2231
2328
|
|
|
2232
2329
|
// src/analyzer/jsdoc-constraints.ts
|
|
2233
|
-
import * as
|
|
2330
|
+
import * as ts4 from "typescript";
|
|
2234
2331
|
|
|
2235
2332
|
// src/analyzer/tsdoc-parser.ts
|
|
2236
|
-
import * as
|
|
2333
|
+
import * as ts3 from "typescript";
|
|
2237
2334
|
import {
|
|
2238
|
-
|
|
2335
|
+
_capabilityLabel,
|
|
2336
|
+
_supportsConstraintCapability,
|
|
2239
2337
|
choosePreferredPayloadText,
|
|
2240
2338
|
extractPathTarget as extractSharedPathTarget,
|
|
2339
|
+
getBroadenedCustomTypeId,
|
|
2241
2340
|
getTagDefinition as getTagDefinition2,
|
|
2242
2341
|
hasTypeSemanticCapability,
|
|
2243
2342
|
normalizeFormSpecTagName as normalizeFormSpecTagName2,
|
|
@@ -2260,25 +2359,10 @@ import { noopLogger as noopLogger3 } from "@formspec/core";
|
|
|
2260
2359
|
|
|
2261
2360
|
// src/extensions/resolve-custom-type.ts
|
|
2262
2361
|
import * as ts2 from "typescript";
|
|
2263
|
-
import { stripNullishUnion } from "@formspec/analysis/internal";
|
|
2362
|
+
import { _collectBrandIdentifiers, stripNullishUnion } from "@formspec/analysis/internal";
|
|
2264
2363
|
|
|
2265
2364
|
// src/extensions/ts-type-utils.ts
|
|
2266
2365
|
import * as ts from "typescript";
|
|
2267
|
-
function collectBrandIdentifiers(type) {
|
|
2268
|
-
if (!type.isIntersection()) {
|
|
2269
|
-
return [];
|
|
2270
|
-
}
|
|
2271
|
-
const brands = [];
|
|
2272
|
-
for (const prop of type.getProperties()) {
|
|
2273
|
-
const decl = prop.valueDeclaration ?? prop.declarations?.[0];
|
|
2274
|
-
if (decl === void 0) continue;
|
|
2275
|
-
if (!ts.isPropertySignature(decl) && !ts.isPropertyDeclaration(decl)) continue;
|
|
2276
|
-
if (!ts.isComputedPropertyName(decl.name)) continue;
|
|
2277
|
-
if (!ts.isIdentifier(decl.name.expression)) continue;
|
|
2278
|
-
brands.push(decl.name.expression.text);
|
|
2279
|
-
}
|
|
2280
|
-
return brands;
|
|
2281
|
-
}
|
|
2282
2366
|
function resolveCanonicalSymbol(type, checker) {
|
|
2283
2367
|
const raw = type.aliasSymbol ?? type.getSymbol();
|
|
2284
2368
|
if (raw === void 0) return void 0;
|
|
@@ -2363,7 +2447,7 @@ function resolveCustomTypeFromTsType(type, checker, registry, sourceNode) {
|
|
|
2363
2447
|
return bySymbol;
|
|
2364
2448
|
}
|
|
2365
2449
|
}
|
|
2366
|
-
for (const brand of
|
|
2450
|
+
for (const brand of _collectBrandIdentifiers(stripped)) {
|
|
2367
2451
|
const byBrand = registry.findTypeByBrand(brand);
|
|
2368
2452
|
if (byBrand !== void 0) {
|
|
2369
2453
|
return byBrand;
|
|
@@ -2376,171 +2460,51 @@ function customTypeIdFromLookup(result) {
|
|
|
2376
2460
|
}
|
|
2377
2461
|
|
|
2378
2462
|
// src/analyzer/builtin-brands.ts
|
|
2379
|
-
import
|
|
2380
|
-
function isIntegerBrandedType(type) {
|
|
2381
|
-
if (!type.isIntersection()) return false;
|
|
2382
|
-
if (!type.types.some((member) => !!(member.flags & ts3.TypeFlags.Number))) return false;
|
|
2383
|
-
return collectBrandIdentifiers(type).includes("__integerBrand");
|
|
2384
|
-
}
|
|
2463
|
+
import { _isIntegerBrandedType } from "@formspec/analysis/internal";
|
|
2385
2464
|
|
|
2386
2465
|
// src/analyzer/tsdoc-parser.ts
|
|
2387
2466
|
import {
|
|
2467
|
+
_emitSetupDiagnostics,
|
|
2388
2468
|
getBuildLogger,
|
|
2389
2469
|
getBroadeningLogger,
|
|
2390
|
-
getSyntheticLogger as getSyntheticLogger2,
|
|
2391
2470
|
getTypedParserLogger,
|
|
2471
|
+
extractEffectiveArgumentText,
|
|
2472
|
+
mapTypedParserDiagnosticCode,
|
|
2392
2473
|
parseTagArgument,
|
|
2393
2474
|
describeTypeKind,
|
|
2394
2475
|
elapsedMicros,
|
|
2395
2476
|
nowMicros,
|
|
2396
2477
|
logTagApplication
|
|
2397
2478
|
} from "@formspec/analysis/internal";
|
|
2398
|
-
function sharedTagValueOptions(options) {
|
|
2479
|
+
function sharedTagValueOptions(options, pathResolvedCustomTypeId) {
|
|
2399
2480
|
return {
|
|
2400
2481
|
...options?.extensionRegistry !== void 0 ? { registry: options.extensionRegistry } : {},
|
|
2401
|
-
...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {}
|
|
2402
|
-
|
|
2403
|
-
}
|
|
2404
|
-
var SYNTHETIC_TYPE_FORMAT_FLAGS = ts4.TypeFormatFlags.NoTruncation | ts4.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
2405
|
-
function getExtensionTypeNames(registry) {
|
|
2406
|
-
if (registry === void 0) {
|
|
2407
|
-
return /* @__PURE__ */ new Set();
|
|
2408
|
-
}
|
|
2409
|
-
return new Set(
|
|
2410
|
-
registry.extensions.flatMap(
|
|
2411
|
-
(ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
|
|
2412
|
-
)
|
|
2413
|
-
);
|
|
2414
|
-
}
|
|
2415
|
-
function collectImportedNames(sourceFile) {
|
|
2416
|
-
const importedNames = /* @__PURE__ */ new Set();
|
|
2417
|
-
for (const statement of sourceFile.statements) {
|
|
2418
|
-
if (ts4.isImportDeclaration(statement) && statement.importClause !== void 0) {
|
|
2419
|
-
const clause = statement.importClause;
|
|
2420
|
-
if (clause.name !== void 0) {
|
|
2421
|
-
importedNames.add(clause.name.text);
|
|
2422
|
-
}
|
|
2423
|
-
if (clause.namedBindings !== void 0) {
|
|
2424
|
-
if (ts4.isNamedImports(clause.namedBindings)) {
|
|
2425
|
-
for (const specifier of clause.namedBindings.elements) {
|
|
2426
|
-
importedNames.add(specifier.name.text);
|
|
2427
|
-
}
|
|
2428
|
-
} else if (ts4.isNamespaceImport(clause.namedBindings)) {
|
|
2429
|
-
importedNames.add(clause.namedBindings.name.text);
|
|
2430
|
-
}
|
|
2431
|
-
}
|
|
2432
|
-
continue;
|
|
2433
|
-
}
|
|
2434
|
-
if (ts4.isImportEqualsDeclaration(statement)) {
|
|
2435
|
-
importedNames.add(statement.name.text);
|
|
2436
|
-
}
|
|
2437
|
-
}
|
|
2438
|
-
return importedNames;
|
|
2439
|
-
}
|
|
2440
|
-
function isNonReferenceIdentifier(node) {
|
|
2441
|
-
const parent = node.parent;
|
|
2442
|
-
if ((ts4.isBindingElement(parent) || ts4.isClassDeclaration(parent) || ts4.isEnumDeclaration(parent) || ts4.isEnumMember(parent) || ts4.isFunctionDeclaration(parent) || ts4.isFunctionExpression(parent) || ts4.isImportClause(parent) || ts4.isImportEqualsDeclaration(parent) || ts4.isImportSpecifier(parent) || ts4.isInterfaceDeclaration(parent) || ts4.isMethodDeclaration(parent) || ts4.isMethodSignature(parent) || ts4.isModuleDeclaration(parent) || ts4.isNamespaceExport(parent) || ts4.isNamespaceImport(parent) || ts4.isParameter(parent) || ts4.isPropertyDeclaration(parent) || ts4.isPropertySignature(parent) || ts4.isSetAccessorDeclaration(parent) || ts4.isGetAccessorDeclaration(parent) || ts4.isTypeAliasDeclaration(parent) || ts4.isTypeParameterDeclaration(parent) || ts4.isVariableDeclaration(parent)) && parent.name === node) {
|
|
2443
|
-
return true;
|
|
2444
|
-
}
|
|
2445
|
-
if ((ts4.isPropertyAssignment(parent) || ts4.isPropertyAccessExpression(parent)) && parent.name === node) {
|
|
2446
|
-
return true;
|
|
2447
|
-
}
|
|
2448
|
-
if (ts4.isQualifiedName(parent) && parent.right === node) {
|
|
2449
|
-
return true;
|
|
2450
|
-
}
|
|
2451
|
-
return false;
|
|
2452
|
-
}
|
|
2453
|
-
function astReferencesImportedName(root, importedNames) {
|
|
2454
|
-
if (importedNames.size === 0) {
|
|
2455
|
-
return false;
|
|
2456
|
-
}
|
|
2457
|
-
let found = false;
|
|
2458
|
-
const visit = (node) => {
|
|
2459
|
-
if (found) return;
|
|
2460
|
-
if (ts4.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
|
|
2461
|
-
found = true;
|
|
2462
|
-
return;
|
|
2463
|
-
}
|
|
2464
|
-
ts4.forEachChild(node, visit);
|
|
2482
|
+
...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {},
|
|
2483
|
+
...pathResolvedCustomTypeId !== void 0 ? { pathResolvedCustomTypeId } : {}
|
|
2465
2484
|
};
|
|
2466
|
-
visit(root);
|
|
2467
|
-
return found;
|
|
2468
2485
|
}
|
|
2469
|
-
function
|
|
2470
|
-
if (
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
if (ts4.isTypeLiteralNode(statement.type)) {
|
|
2474
|
-
return statement.type.members;
|
|
2475
|
-
}
|
|
2476
|
-
return void 0;
|
|
2486
|
+
function customTypeIdForResolvedType(resolvedType, checker, registry) {
|
|
2487
|
+
if (registry === void 0) return void 0;
|
|
2488
|
+
const lookup = resolveCustomTypeFromTsType(resolvedType, checker, registry);
|
|
2489
|
+
return lookup === null ? void 0 : customTypeIdFromLookup(lookup);
|
|
2477
2490
|
}
|
|
2478
|
-
function
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
const replacements = [];
|
|
2484
|
-
for (const member of members) {
|
|
2485
|
-
if (!ts4.isPropertySignature(member)) {
|
|
2486
|
-
if (astReferencesImportedName(member, importedNames)) {
|
|
2487
|
-
return null;
|
|
2488
|
-
}
|
|
2489
|
-
continue;
|
|
2490
|
-
}
|
|
2491
|
-
const typeAnnotation = member.type;
|
|
2492
|
-
if (typeAnnotation === void 0) continue;
|
|
2493
|
-
if (astReferencesImportedName(typeAnnotation, importedNames)) {
|
|
2494
|
-
replacements.push({
|
|
2495
|
-
start: typeAnnotation.getStart(sourceFile),
|
|
2496
|
-
end: typeAnnotation.getEnd()
|
|
2497
|
-
});
|
|
2498
|
-
}
|
|
2499
|
-
}
|
|
2500
|
-
if (replacements.length === 0) {
|
|
2501
|
-
return statement.getText(sourceFile);
|
|
2502
|
-
}
|
|
2503
|
-
const stmtStart = statement.getStart(sourceFile);
|
|
2504
|
-
let result = statement.getText(sourceFile);
|
|
2505
|
-
for (const { start, end } of [...replacements].reverse()) {
|
|
2506
|
-
result = result.slice(0, start - stmtStart) + "unknown" + result.slice(end - stmtStart);
|
|
2491
|
+
function resolvePathTargetCustomTypeId(parsedTag, subjectType, checker, registry) {
|
|
2492
|
+
if (parsedTag === null) return void 0;
|
|
2493
|
+
const target = parsedTag.target;
|
|
2494
|
+
if (target?.kind !== "path" || !target.valid || target.path === null) {
|
|
2495
|
+
return void 0;
|
|
2507
2496
|
}
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
|
|
2511
|
-
const importedNames = collectImportedNames(sourceFile);
|
|
2512
|
-
const importedNamesToSkip = new Set(
|
|
2513
|
-
[...importedNames].filter((name) => !extensionTypeNames.has(name))
|
|
2514
|
-
);
|
|
2515
|
-
const result = [];
|
|
2516
|
-
for (const statement of sourceFile.statements) {
|
|
2517
|
-
if (ts4.isImportDeclaration(statement)) continue;
|
|
2518
|
-
if (ts4.isImportEqualsDeclaration(statement)) continue;
|
|
2519
|
-
if (ts4.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0) continue;
|
|
2520
|
-
if (!astReferencesImportedName(statement, importedNamesToSkip)) {
|
|
2521
|
-
result.push(statement.getText(sourceFile));
|
|
2522
|
-
continue;
|
|
2523
|
-
}
|
|
2524
|
-
if (ts4.isInterfaceDeclaration(statement) || ts4.isTypeAliasDeclaration(statement)) {
|
|
2525
|
-
const rewritten = rewriteImportedMemberTypes(statement, sourceFile, importedNamesToSkip);
|
|
2526
|
-
if (rewritten !== null) {
|
|
2527
|
-
result.push(rewritten);
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2497
|
+
if (subjectType === void 0 || checker === void 0) {
|
|
2498
|
+
return void 0;
|
|
2530
2499
|
}
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
for (const diagnostic of additions) {
|
|
2535
|
-
if ((diagnostic.code === "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" || diagnostic.code === "SYNTHETIC_SETUP_FAILURE") && target.some(
|
|
2536
|
-
(existing) => existing.code === diagnostic.code && existing.message === diagnostic.message
|
|
2537
|
-
)) {
|
|
2538
|
-
continue;
|
|
2539
|
-
}
|
|
2540
|
-
target.push(diagnostic);
|
|
2500
|
+
const resolution = resolvePathTargetType(subjectType, checker, target.path.segments);
|
|
2501
|
+
if (resolution.kind !== "resolved") {
|
|
2502
|
+
return void 0;
|
|
2541
2503
|
}
|
|
2504
|
+
return customTypeIdForResolvedType(resolution.type, checker, registry);
|
|
2542
2505
|
}
|
|
2543
|
-
|
|
2506
|
+
var TYPE_FORMAT_FLAGS = ts3.TypeFormatFlags.NoTruncation | ts3.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
2507
|
+
function processConstraintTag(tagName, text, parsedTag, provenance, node, sourceFile, options, constraints, diagnostics) {
|
|
2544
2508
|
const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
|
|
2545
2509
|
node,
|
|
2546
2510
|
sourceFile,
|
|
@@ -2548,74 +2512,30 @@ function processConstraintTag(tagName, text, parsedTag, provenance, node, source
|
|
|
2548
2512
|
parsedTag,
|
|
2549
2513
|
text,
|
|
2550
2514
|
provenance,
|
|
2551
|
-
supportingDeclarations,
|
|
2552
2515
|
options
|
|
2553
2516
|
);
|
|
2554
2517
|
if (compilerDiagnostics.length > 0) {
|
|
2555
|
-
|
|
2518
|
+
diagnostics.push(...compilerDiagnostics);
|
|
2556
2519
|
return;
|
|
2557
2520
|
}
|
|
2521
|
+
const pathResolvedCustomTypeId = resolvePathTargetCustomTypeId(
|
|
2522
|
+
parsedTag,
|
|
2523
|
+
options?.subjectType,
|
|
2524
|
+
options?.checker,
|
|
2525
|
+
options?.extensionRegistry
|
|
2526
|
+
);
|
|
2558
2527
|
const constraintNode = parseConstraintTagValue(
|
|
2559
2528
|
tagName,
|
|
2560
2529
|
text,
|
|
2561
2530
|
provenance,
|
|
2562
|
-
sharedTagValueOptions(options)
|
|
2531
|
+
sharedTagValueOptions(options, pathResolvedCustomTypeId)
|
|
2563
2532
|
);
|
|
2564
2533
|
if (constraintNode) {
|
|
2565
2534
|
constraints.push(constraintNode);
|
|
2566
2535
|
}
|
|
2567
2536
|
}
|
|
2568
|
-
function renderSyntheticArgumentExpression(valueKind, argumentText) {
|
|
2569
|
-
const trimmed = argumentText.trim();
|
|
2570
|
-
if (trimmed === "") {
|
|
2571
|
-
return null;
|
|
2572
|
-
}
|
|
2573
|
-
switch (valueKind) {
|
|
2574
|
-
case "number":
|
|
2575
|
-
case "integer":
|
|
2576
|
-
case "signedInteger":
|
|
2577
|
-
if (trimmed === "Infinity" || trimmed === "-Infinity" || trimmed === "NaN") {
|
|
2578
|
-
return trimmed;
|
|
2579
|
-
}
|
|
2580
|
-
return Number.isFinite(Number(trimmed)) ? trimmed : JSON.stringify(trimmed);
|
|
2581
|
-
case "string":
|
|
2582
|
-
return JSON.stringify(argumentText);
|
|
2583
|
-
case "json":
|
|
2584
|
-
try {
|
|
2585
|
-
JSON.parse(trimmed);
|
|
2586
|
-
return `(${trimmed})`;
|
|
2587
|
-
} catch {
|
|
2588
|
-
return JSON.stringify(trimmed);
|
|
2589
|
-
}
|
|
2590
|
-
case "boolean":
|
|
2591
|
-
return trimmed === "true" || trimmed === "false" ? trimmed : JSON.stringify(trimmed);
|
|
2592
|
-
case "condition":
|
|
2593
|
-
return "undefined as unknown as FormSpecCondition";
|
|
2594
|
-
case null:
|
|
2595
|
-
return null;
|
|
2596
|
-
default: {
|
|
2597
|
-
return String(valueKind);
|
|
2598
|
-
}
|
|
2599
|
-
}
|
|
2600
|
-
}
|
|
2601
|
-
function getArrayElementType(type, checker) {
|
|
2602
|
-
if (!checker.isArrayType(type)) {
|
|
2603
|
-
return null;
|
|
2604
|
-
}
|
|
2605
|
-
return checker.getTypeArguments(type)[0] ?? null;
|
|
2606
|
-
}
|
|
2607
2537
|
function supportsConstraintCapability(type, checker, capability) {
|
|
2608
|
-
|
|
2609
|
-
return true;
|
|
2610
|
-
}
|
|
2611
|
-
if (hasTypeSemanticCapability(type, checker, capability)) {
|
|
2612
|
-
return true;
|
|
2613
|
-
}
|
|
2614
|
-
if (capability === "string-like") {
|
|
2615
|
-
const itemType = getArrayElementType(type, checker);
|
|
2616
|
-
return itemType !== null && hasTypeSemanticCapability(itemType, checker, capability);
|
|
2617
|
-
}
|
|
2618
|
-
return false;
|
|
2538
|
+
return _supportsConstraintCapability(capability, type, checker);
|
|
2619
2539
|
}
|
|
2620
2540
|
var MAX_HINT_CANDIDATES = 5;
|
|
2621
2541
|
var MAX_HINT_DEPTH = 3;
|
|
@@ -2624,7 +2544,7 @@ function stripHintNullishUnion(type) {
|
|
|
2624
2544
|
return type;
|
|
2625
2545
|
}
|
|
2626
2546
|
const nonNullish = type.types.filter(
|
|
2627
|
-
(member) => (member.flags & (
|
|
2547
|
+
(member) => (member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined)) === 0
|
|
2628
2548
|
);
|
|
2629
2549
|
if (nonNullish.length === 1 && nonNullish[0] !== void 0) {
|
|
2630
2550
|
return nonNullish[0];
|
|
@@ -2640,10 +2560,10 @@ function isUserEmittableHintProperty(property, declaration) {
|
|
|
2640
2560
|
}
|
|
2641
2561
|
if ("name" in declaration && declaration.name !== void 0) {
|
|
2642
2562
|
const name = declaration.name;
|
|
2643
|
-
if (
|
|
2563
|
+
if (ts3.isComputedPropertyName(name) || ts3.isPrivateIdentifier(name)) {
|
|
2644
2564
|
return false;
|
|
2645
2565
|
}
|
|
2646
|
-
if (!
|
|
2566
|
+
if (!ts3.isIdentifier(name) && !ts3.isStringLiteral(name) && !ts3.isNumericLiteral(name)) {
|
|
2647
2567
|
return false;
|
|
2648
2568
|
}
|
|
2649
2569
|
}
|
|
@@ -2742,53 +2662,11 @@ function placementLabel(placement) {
|
|
|
2742
2662
|
}
|
|
2743
2663
|
}
|
|
2744
2664
|
}
|
|
2745
|
-
function capabilityLabel(capability) {
|
|
2746
|
-
switch (capability) {
|
|
2747
|
-
case "numeric-comparable":
|
|
2748
|
-
return "number";
|
|
2749
|
-
case "string-like":
|
|
2750
|
-
return "string";
|
|
2751
|
-
case "array-like":
|
|
2752
|
-
return "array";
|
|
2753
|
-
case "enum-member-addressable":
|
|
2754
|
-
return "enum";
|
|
2755
|
-
case "json-like":
|
|
2756
|
-
return "JSON-compatible";
|
|
2757
|
-
case "object-like":
|
|
2758
|
-
return "object";
|
|
2759
|
-
case "condition-like":
|
|
2760
|
-
return "conditional";
|
|
2761
|
-
case void 0:
|
|
2762
|
-
return "compatible";
|
|
2763
|
-
default:
|
|
2764
|
-
return capability;
|
|
2765
|
-
}
|
|
2766
|
-
}
|
|
2767
|
-
function getBroadenedCustomTypeId(fieldType) {
|
|
2768
|
-
if (fieldType?.kind === "custom") {
|
|
2769
|
-
return fieldType.typeId;
|
|
2770
|
-
}
|
|
2771
|
-
if (fieldType?.kind !== "union") {
|
|
2772
|
-
return void 0;
|
|
2773
|
-
}
|
|
2774
|
-
const customMembers = fieldType.members.filter(
|
|
2775
|
-
(member) => member.kind === "custom"
|
|
2776
|
-
);
|
|
2777
|
-
if (customMembers.length !== 1) {
|
|
2778
|
-
return void 0;
|
|
2779
|
-
}
|
|
2780
|
-
const nonCustomMembers = fieldType.members.filter((member) => member.kind !== "custom");
|
|
2781
|
-
const allOtherMembersAreNull = nonCustomMembers.every(
|
|
2782
|
-
(member) => member.kind === "primitive" && member.primitiveKind === "null"
|
|
2783
|
-
);
|
|
2784
|
-
const customMember = customMembers[0];
|
|
2785
|
-
return allOtherMembersAreNull && customMember !== void 0 ? customMember.typeId : void 0;
|
|
2786
|
-
}
|
|
2787
2665
|
function hasBuiltinConstraintBroadening(tagName, options) {
|
|
2788
2666
|
const broadenedTypeId = getBroadenedCustomTypeId(options?.fieldType);
|
|
2789
2667
|
return broadenedTypeId !== void 0 && options?.extensionRegistry?.findBuiltinConstraintBroadening(broadenedTypeId, tagName) !== void 0;
|
|
2790
2668
|
}
|
|
2791
|
-
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance,
|
|
2669
|
+
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance, options) {
|
|
2792
2670
|
if (!isBuiltinConstraintName(tagName)) {
|
|
2793
2671
|
return [];
|
|
2794
2672
|
}
|
|
@@ -2808,16 +2686,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2808
2686
|
const nonNullPlacement = placement;
|
|
2809
2687
|
const log = getBuildLogger();
|
|
2810
2688
|
const broadeningLog = getBroadeningLogger();
|
|
2811
|
-
const syntheticLog = getSyntheticLogger2();
|
|
2812
2689
|
const typedParserLog = getTypedParserLogger();
|
|
2813
2690
|
const logsEnabled = log !== noopLogger3 || broadeningLog !== noopLogger3;
|
|
2814
|
-
const syntheticTraceEnabled = syntheticLog !== noopLogger3;
|
|
2815
2691
|
const typedParserTraceEnabled = typedParserLog !== noopLogger3;
|
|
2816
2692
|
const logStart = logsEnabled ? nowMicros() : 0;
|
|
2817
2693
|
const subjectTypeKind = logsEnabled ? describeTypeKind(subjectType, checker) : "";
|
|
2818
|
-
function emit(outcome,
|
|
2694
|
+
function emit(outcome, result) {
|
|
2819
2695
|
if (!logsEnabled) {
|
|
2820
|
-
return
|
|
2696
|
+
return result;
|
|
2821
2697
|
}
|
|
2822
2698
|
const entry = {
|
|
2823
2699
|
consumer: "build",
|
|
@@ -2831,7 +2707,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2831
2707
|
if (outcome === "bypass" || outcome === "D1" || outcome === "D2") {
|
|
2832
2708
|
logTagApplication(broadeningLog, entry);
|
|
2833
2709
|
}
|
|
2834
|
-
return
|
|
2710
|
+
return result;
|
|
2835
2711
|
}
|
|
2836
2712
|
if (!definition.placements.includes(placement)) {
|
|
2837
2713
|
return emit("A-reject", [
|
|
@@ -2875,7 +2751,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2875
2751
|
]);
|
|
2876
2752
|
}
|
|
2877
2753
|
if (resolution.kind === "unresolvable") {
|
|
2878
|
-
const actualType = checker.typeToString(resolution.type, node,
|
|
2754
|
+
const actualType = checker.typeToString(resolution.type, node, TYPE_FORMAT_FLAGS);
|
|
2879
2755
|
return emit("B-reject", [
|
|
2880
2756
|
makeDiagnostic(
|
|
2881
2757
|
"TYPE_MISMATCH",
|
|
@@ -2889,21 +2765,21 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2889
2765
|
}
|
|
2890
2766
|
const hasBroadening = (() => {
|
|
2891
2767
|
if (target === null) {
|
|
2892
|
-
if (
|
|
2768
|
+
if (_isIntegerBrandedType(stripNullishUnion2(subjectType)) && definition.capabilities[0] === "numeric-comparable") {
|
|
2893
2769
|
return true;
|
|
2894
2770
|
}
|
|
2895
2771
|
return hasBuiltinConstraintBroadening(tagName, options);
|
|
2896
2772
|
}
|
|
2897
2773
|
const registry = options?.extensionRegistry;
|
|
2898
2774
|
if (registry === void 0) return false;
|
|
2899
|
-
const
|
|
2900
|
-
return
|
|
2775
|
+
const typeId = customTypeIdForResolvedType(evaluatedType, checker, registry);
|
|
2776
|
+
return typeId !== void 0 && registry.findBuiltinConstraintBroadening(typeId, tagName) !== void 0;
|
|
2901
2777
|
})();
|
|
2902
2778
|
if (!hasBroadening) {
|
|
2903
2779
|
const requiredCapability = definition.capabilities[0];
|
|
2904
2780
|
if (requiredCapability !== void 0 && !supportsConstraintCapability(evaluatedType, checker, requiredCapability)) {
|
|
2905
|
-
const actualType = checker.typeToString(evaluatedType, node,
|
|
2906
|
-
const baseMessage = `Target "${targetLabel}": constraint "${tagName}" is only valid on ${
|
|
2781
|
+
const actualType = checker.typeToString(evaluatedType, node, TYPE_FORMAT_FLAGS);
|
|
2782
|
+
const baseMessage = `Target "${targetLabel}": constraint "${tagName}" is only valid on ${_capabilityLabel(requiredCapability)} targets, but field type is "${actualType}"`;
|
|
2907
2783
|
const hint = target === null ? buildPathTargetHint(
|
|
2908
2784
|
subjectType,
|
|
2909
2785
|
checker,
|
|
@@ -2920,10 +2796,10 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2920
2796
|
]);
|
|
2921
2797
|
}
|
|
2922
2798
|
}
|
|
2923
|
-
const effectiveArgumentText = parsedTag !== null ? parseTagSyntax(tagName, rawText).argumentText : rawText;
|
|
2924
2799
|
if (hasBroadening) {
|
|
2925
2800
|
return emit("bypass", []);
|
|
2926
2801
|
}
|
|
2802
|
+
const effectiveArgumentText = extractEffectiveArgumentText(tagName, rawText, parsedTag);
|
|
2927
2803
|
const typedParseResult = parseTagArgument(tagName, effectiveArgumentText, "build");
|
|
2928
2804
|
if (!typedParseResult.ok) {
|
|
2929
2805
|
if (typedParserTraceEnabled) {
|
|
@@ -2936,23 +2812,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2936
2812
|
diagnosticCode: typedParseResult.diagnostic.code
|
|
2937
2813
|
});
|
|
2938
2814
|
}
|
|
2939
|
-
|
|
2940
|
-
switch (typedParseResult.diagnostic.code) {
|
|
2941
|
-
case "MISSING_TAG_ARGUMENT":
|
|
2942
|
-
mappedCode = "MISSING_TAG_ARGUMENT";
|
|
2943
|
-
break;
|
|
2944
|
-
case "INVALID_TAG_ARGUMENT":
|
|
2945
|
-
mappedCode = "INVALID_TAG_ARGUMENT";
|
|
2946
|
-
break;
|
|
2947
|
-
case "UNKNOWN_TAG":
|
|
2948
|
-
throw new Error(
|
|
2949
|
-
`Unexpected UNKNOWN_TAG from parseTagArgument("${tagName}") \u2014 tag was resolved via getTagDefinition.`
|
|
2950
|
-
);
|
|
2951
|
-
default: {
|
|
2952
|
-
const _exhaustive = typedParseResult.diagnostic.code;
|
|
2953
|
-
throw new Error(`Unknown diagnostic code: ${String(_exhaustive)}`);
|
|
2954
|
-
}
|
|
2955
|
-
}
|
|
2815
|
+
const mappedCode = mapTypedParserDiagnosticCode(typedParseResult.diagnostic.code, tagName);
|
|
2956
2816
|
return emit("C-reject", [
|
|
2957
2817
|
makeDiagnostic(mappedCode, typedParseResult.diagnostic.message, provenance)
|
|
2958
2818
|
]);
|
|
@@ -2967,68 +2827,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2967
2827
|
valueKind: typedParseResult.value.kind
|
|
2968
2828
|
});
|
|
2969
2829
|
}
|
|
2970
|
-
|
|
2971
|
-
definition.valueKind,
|
|
2972
|
-
effectiveArgumentText
|
|
2973
|
-
);
|
|
2974
|
-
const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2975
|
-
const hostType = options?.hostType ?? subjectType;
|
|
2976
|
-
const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2977
|
-
if (syntheticTraceEnabled) {
|
|
2978
|
-
syntheticLog.trace("invoking synthetic checker", {
|
|
2979
|
-
consumer: "build",
|
|
2980
|
-
tag: tagName,
|
|
2981
|
-
placement,
|
|
2982
|
-
subjectTypeKind,
|
|
2983
|
-
subjectTypeText
|
|
2984
|
-
});
|
|
2985
|
-
}
|
|
2986
|
-
const result = checkSyntheticTagApplication({
|
|
2987
|
-
tagName,
|
|
2988
|
-
placement,
|
|
2989
|
-
hostType: hostTypeText,
|
|
2990
|
-
subjectType: subjectTypeText,
|
|
2991
|
-
...target?.kind === "path" ? { target: { kind: "path", text: target.rawText } } : {},
|
|
2992
|
-
...argumentExpression !== null ? { argumentExpression } : {},
|
|
2993
|
-
supportingDeclarations,
|
|
2994
|
-
...options?.extensionRegistry !== void 0 ? {
|
|
2995
|
-
extensions: options.extensionRegistry.extensions.map((extension) => ({
|
|
2996
|
-
extensionId: extension.extensionId,
|
|
2997
|
-
...extension.constraintTags !== void 0 ? {
|
|
2998
|
-
constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
|
|
2999
|
-
} : {},
|
|
3000
|
-
...extension.metadataSlots !== void 0 ? {
|
|
3001
|
-
metadataSlots: extension.metadataSlots
|
|
3002
|
-
} : {},
|
|
3003
|
-
...extension.types !== void 0 ? {
|
|
3004
|
-
customTypes: extension.types.map((t) => ({
|
|
3005
|
-
tsTypeNames: t.tsTypeNames ?? [t.typeName]
|
|
3006
|
-
}))
|
|
3007
|
-
} : {}
|
|
3008
|
-
}))
|
|
3009
|
-
} : {}
|
|
3010
|
-
});
|
|
3011
|
-
if (result.diagnostics.length === 0) {
|
|
3012
|
-
return emit("C-pass", []);
|
|
3013
|
-
}
|
|
3014
|
-
const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
|
|
3015
|
-
if (setupDiagnostic !== void 0) {
|
|
3016
|
-
return emit("C-reject", [
|
|
3017
|
-
makeDiagnostic(
|
|
3018
|
-
setupDiagnostic.kind === "unsupported-custom-type-override" ? "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" : "SYNTHETIC_SETUP_FAILURE",
|
|
3019
|
-
setupDiagnostic.message,
|
|
3020
|
-
provenance
|
|
3021
|
-
)
|
|
3022
|
-
]);
|
|
3023
|
-
}
|
|
3024
|
-
const expectedLabel = definition.valueKind === null ? "compatible argument" : capabilityLabel(definition.valueKind);
|
|
3025
|
-
return emit("C-reject", [
|
|
3026
|
-
makeDiagnostic(
|
|
3027
|
-
"TYPE_MISMATCH",
|
|
3028
|
-
`Tag "@${tagName}" received an invalid argument for ${expectedLabel}.`,
|
|
3029
|
-
provenance
|
|
3030
|
-
)
|
|
3031
|
-
]);
|
|
2830
|
+
return emit("C-pass", []);
|
|
3032
2831
|
}
|
|
3033
2832
|
var parseResultCache = /* @__PURE__ */ new Map();
|
|
3034
2833
|
function getExtensionTagNames(options) {
|
|
@@ -3072,8 +2871,8 @@ function getParseCacheKey(node, file, options) {
|
|
|
3072
2871
|
start: node.getFullStart(),
|
|
3073
2872
|
end: node.getEnd(),
|
|
3074
2873
|
fieldType: options?.fieldType ?? null,
|
|
3075
|
-
subjectType: checker !== void 0 && options?.subjectType !== void 0 ? checker.typeToString(options.subjectType, node,
|
|
3076
|
-
hostType: checker !== void 0 && options?.hostType !== void 0 ? checker.typeToString(options.hostType, node,
|
|
2874
|
+
subjectType: checker !== void 0 && options?.subjectType !== void 0 ? checker.typeToString(options.subjectType, node, TYPE_FORMAT_FLAGS) : null,
|
|
2875
|
+
hostType: checker !== void 0 && options?.hostType !== void 0 ? checker.typeToString(options.hostType, node, TYPE_FORMAT_FLAGS) : null,
|
|
3077
2876
|
extensions: getExtensionRegistryCacheKey(options?.extensionRegistry)
|
|
3078
2877
|
});
|
|
3079
2878
|
}
|
|
@@ -3083,6 +2882,16 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3083
2882
|
if (cached !== void 0) {
|
|
3084
2883
|
return cached;
|
|
3085
2884
|
}
|
|
2885
|
+
const setupDiags = options?.extensionRegistry?.setupDiagnostics;
|
|
2886
|
+
if (setupDiags !== void 0 && setupDiags.length > 0) {
|
|
2887
|
+
const result2 = {
|
|
2888
|
+
constraints: [],
|
|
2889
|
+
annotations: [],
|
|
2890
|
+
diagnostics: _emitSetupDiagnostics(setupDiags, file)
|
|
2891
|
+
};
|
|
2892
|
+
parseResultCache.set(cacheKey, result2);
|
|
2893
|
+
return result2;
|
|
2894
|
+
}
|
|
3086
2895
|
const constraints = [];
|
|
3087
2896
|
const annotations = [];
|
|
3088
2897
|
const diagnostics = [];
|
|
@@ -3092,14 +2901,12 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3092
2901
|
let placeholderProvenance;
|
|
3093
2902
|
const sourceFile = node.getSourceFile();
|
|
3094
2903
|
const sourceText = sourceFile.getFullText();
|
|
3095
|
-
const
|
|
3096
|
-
const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
|
|
3097
|
-
const commentRanges = ts4.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
2904
|
+
const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
3098
2905
|
const rawTextFallbacks = collectRawTextFallbacks(node, file);
|
|
3099
2906
|
const extensionTagNames = getExtensionTagNames(options);
|
|
3100
2907
|
if (commentRanges) {
|
|
3101
2908
|
for (const range of commentRanges) {
|
|
3102
|
-
if (range.kind !==
|
|
2909
|
+
if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) {
|
|
3103
2910
|
continue;
|
|
3104
2911
|
}
|
|
3105
2912
|
const commentText = sourceText.substring(range.pos, range.end);
|
|
@@ -3158,7 +2965,6 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3158
2965
|
provenance2,
|
|
3159
2966
|
node,
|
|
3160
2967
|
sourceFile,
|
|
3161
|
-
supportingDeclarations,
|
|
3162
2968
|
options,
|
|
3163
2969
|
constraints,
|
|
3164
2970
|
diagnostics
|
|
@@ -3176,7 +2982,6 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3176
2982
|
provenance,
|
|
3177
2983
|
node,
|
|
3178
2984
|
sourceFile,
|
|
3179
|
-
supportingDeclarations,
|
|
3180
2985
|
options,
|
|
3181
2986
|
constraints,
|
|
3182
2987
|
diagnostics
|
|
@@ -3240,7 +3045,6 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3240
3045
|
provenance,
|
|
3241
3046
|
node,
|
|
3242
3047
|
sourceFile,
|
|
3243
|
-
supportingDeclarations,
|
|
3244
3048
|
options,
|
|
3245
3049
|
constraints,
|
|
3246
3050
|
diagnostics
|
|
@@ -3256,10 +3060,10 @@ function extractDisplayNameMetadata(node) {
|
|
|
3256
3060
|
const memberDisplayNames = /* @__PURE__ */ new Map();
|
|
3257
3061
|
const sourceFile = node.getSourceFile();
|
|
3258
3062
|
const sourceText = sourceFile.getFullText();
|
|
3259
|
-
const commentRanges =
|
|
3063
|
+
const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
3260
3064
|
if (commentRanges) {
|
|
3261
3065
|
for (const range of commentRanges) {
|
|
3262
|
-
if (range.kind !==
|
|
3066
|
+
if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) continue;
|
|
3263
3067
|
const commentText = sourceText.substring(range.pos, range.end);
|
|
3264
3068
|
if (!commentText.startsWith("/**")) continue;
|
|
3265
3069
|
const unified = parseUnifiedComment(commentText);
|
|
@@ -3284,7 +3088,7 @@ function extractDisplayNameMetadata(node) {
|
|
|
3284
3088
|
}
|
|
3285
3089
|
function collectRawTextFallbacks(node, file) {
|
|
3286
3090
|
const fallbacks = /* @__PURE__ */ new Map();
|
|
3287
|
-
for (const tag of
|
|
3091
|
+
for (const tag of ts3.getJSDocTags(node)) {
|
|
3288
3092
|
const tagName = normalizeConstraintTagName2(tag.tagName.text);
|
|
3289
3093
|
if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
3290
3094
|
const commentText = getTagCommentText(tag)?.trim() ?? "";
|
|
@@ -3339,7 +3143,7 @@ function getTagCommentText(tag) {
|
|
|
3339
3143
|
if (typeof tag.comment === "string") {
|
|
3340
3144
|
return tag.comment;
|
|
3341
3145
|
}
|
|
3342
|
-
return
|
|
3146
|
+
return ts3.getTextOfJSDocComment(tag.comment);
|
|
3343
3147
|
}
|
|
3344
3148
|
|
|
3345
3149
|
// src/analyzer/jsdoc-constraints.ts
|
|
@@ -3357,18 +3161,18 @@ function extractJSDocAnnotationNodes(node, file = "", options) {
|
|
|
3357
3161
|
function extractDefaultValueAnnotation(initializer, file = "") {
|
|
3358
3162
|
if (!initializer) return null;
|
|
3359
3163
|
let value;
|
|
3360
|
-
if (
|
|
3164
|
+
if (ts4.isStringLiteral(initializer)) {
|
|
3361
3165
|
value = initializer.text;
|
|
3362
|
-
} else if (
|
|
3166
|
+
} else if (ts4.isNumericLiteral(initializer)) {
|
|
3363
3167
|
value = Number(initializer.text);
|
|
3364
|
-
} else if (initializer.kind ===
|
|
3168
|
+
} else if (initializer.kind === ts4.SyntaxKind.TrueKeyword) {
|
|
3365
3169
|
value = true;
|
|
3366
|
-
} else if (initializer.kind ===
|
|
3170
|
+
} else if (initializer.kind === ts4.SyntaxKind.FalseKeyword) {
|
|
3367
3171
|
value = false;
|
|
3368
|
-
} else if (initializer.kind ===
|
|
3172
|
+
} else if (initializer.kind === ts4.SyntaxKind.NullKeyword) {
|
|
3369
3173
|
value = null;
|
|
3370
|
-
} else if (
|
|
3371
|
-
if (initializer.operator ===
|
|
3174
|
+
} else if (ts4.isPrefixUnaryExpression(initializer)) {
|
|
3175
|
+
if (initializer.operator === ts4.SyntaxKind.MinusToken && ts4.isNumericLiteral(initializer.operand)) {
|
|
3372
3176
|
value = -Number(initializer.operand.text);
|
|
3373
3177
|
}
|
|
3374
3178
|
}
|
|
@@ -3390,28 +3194,28 @@ function extractDefaultValueAnnotation(initializer, file = "") {
|
|
|
3390
3194
|
|
|
3391
3195
|
// src/analyzer/class-analyzer.ts
|
|
3392
3196
|
function isObjectType(type) {
|
|
3393
|
-
return !!(type.flags &
|
|
3197
|
+
return !!(type.flags & ts5.TypeFlags.Object);
|
|
3394
3198
|
}
|
|
3395
3199
|
function isIntersectionType(type) {
|
|
3396
|
-
return !!(type.flags &
|
|
3200
|
+
return !!(type.flags & ts5.TypeFlags.Intersection);
|
|
3397
3201
|
}
|
|
3398
3202
|
function isResolvableObjectLikeAliasTypeNode(typeNode) {
|
|
3399
|
-
if (
|
|
3203
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
3400
3204
|
return isResolvableObjectLikeAliasTypeNode(typeNode.type);
|
|
3401
3205
|
}
|
|
3402
|
-
if (
|
|
3206
|
+
if (ts5.isTypeLiteralNode(typeNode) || ts5.isTypeReferenceNode(typeNode)) {
|
|
3403
3207
|
return true;
|
|
3404
3208
|
}
|
|
3405
|
-
return
|
|
3209
|
+
return ts5.isIntersectionTypeNode(typeNode) && typeNode.types.length > 0 && typeNode.types.every((member) => isResolvableObjectLikeAliasTypeNode(member));
|
|
3406
3210
|
}
|
|
3407
3211
|
function isSemanticallyPlainObjectLikeType(type, checker) {
|
|
3408
3212
|
if (isIntersectionType(type)) {
|
|
3409
3213
|
return type.types.length > 0 && type.types.every((member) => isSemanticallyPlainObjectLikeType(member, checker));
|
|
3410
3214
|
}
|
|
3411
|
-
return isObjectType(type) && checker.getSignaturesOfType(type,
|
|
3215
|
+
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);
|
|
3412
3216
|
}
|
|
3413
3217
|
function isTypeReference(type) {
|
|
3414
|
-
return !!(type.flags &
|
|
3218
|
+
return !!(type.flags & ts5.TypeFlags.Object) && !!(type.objectFlags & ts5.ObjectFlags.Reference);
|
|
3415
3219
|
}
|
|
3416
3220
|
var RESOLVING_TYPE_PLACEHOLDER = {
|
|
3417
3221
|
kind: "object",
|
|
@@ -3437,6 +3241,21 @@ function createAnalyzerMetadataPolicy(input, discriminator) {
|
|
|
3437
3241
|
discriminator
|
|
3438
3242
|
};
|
|
3439
3243
|
}
|
|
3244
|
+
var DEDUPLICATABLE_DIAGNOSTIC_CODES = /* @__PURE__ */ new Set([
|
|
3245
|
+
"SYNTHETIC_SETUP_FAILURE",
|
|
3246
|
+
"UNSUPPORTED_CUSTOM_TYPE_OVERRIDE"
|
|
3247
|
+
]);
|
|
3248
|
+
function deduplicateDiagnostics(diagnostics) {
|
|
3249
|
+
if (diagnostics.length <= 1) return diagnostics;
|
|
3250
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3251
|
+
return diagnostics.filter((d) => {
|
|
3252
|
+
if (!DEDUPLICATABLE_DIAGNOSTIC_CODES.has(d.code)) return true;
|
|
3253
|
+
const key = `${d.code}\0${d.message}`;
|
|
3254
|
+
if (seen.has(key)) return false;
|
|
3255
|
+
seen.add(key);
|
|
3256
|
+
return true;
|
|
3257
|
+
});
|
|
3258
|
+
}
|
|
3440
3259
|
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
3441
3260
|
const analysis = analyzeMetadataForNodeWithChecker({
|
|
3442
3261
|
checker,
|
|
@@ -3473,10 +3292,121 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
|
|
|
3473
3292
|
}
|
|
3474
3293
|
return resolvedMetadata;
|
|
3475
3294
|
}
|
|
3295
|
+
var INHERITABLE_TYPE_ANNOTATION_KINDS = /* @__PURE__ */ new Set(["format"]);
|
|
3296
|
+
function getInheritableAnnotationStringValue(annotation) {
|
|
3297
|
+
if (annotation.annotationKind === "format") return annotation.value;
|
|
3298
|
+
return void 0;
|
|
3299
|
+
}
|
|
3300
|
+
function isOverridingInheritableAnnotation(annotation) {
|
|
3301
|
+
const value = getInheritableAnnotationStringValue(annotation);
|
|
3302
|
+
if (value === void 0) return true;
|
|
3303
|
+
return value.trim().length > 0;
|
|
3304
|
+
}
|
|
3305
|
+
function collectInheritedTypeAnnotations(derivedDecl, existingAnnotations, checker, extensionRegistry) {
|
|
3306
|
+
const existingKinds = new Set(
|
|
3307
|
+
existingAnnotations.filter(isOverridingInheritableAnnotation).map((a) => a.annotationKind)
|
|
3308
|
+
);
|
|
3309
|
+
const needed = /* @__PURE__ */ new Set();
|
|
3310
|
+
for (const kind of INHERITABLE_TYPE_ANNOTATION_KINDS) {
|
|
3311
|
+
if (!existingKinds.has(kind)) needed.add(kind);
|
|
3312
|
+
}
|
|
3313
|
+
if (needed.size === 0) return [];
|
|
3314
|
+
const inherited = [];
|
|
3315
|
+
const seen = /* @__PURE__ */ new Set([derivedDecl]);
|
|
3316
|
+
const queue = [];
|
|
3317
|
+
const resolveSymbolTarget = (sym) => {
|
|
3318
|
+
if ((sym.flags & ts5.SymbolFlags.Alias) === 0) return sym;
|
|
3319
|
+
try {
|
|
3320
|
+
return checker.getAliasedSymbol(sym);
|
|
3321
|
+
} catch {
|
|
3322
|
+
return sym;
|
|
3323
|
+
}
|
|
3324
|
+
};
|
|
3325
|
+
const isObjectShapedTypeAlias = (alias) => {
|
|
3326
|
+
const type = checker.getTypeFromTypeNode(alias.type);
|
|
3327
|
+
if ((type.flags & ts5.TypeFlags.Object) !== 0) return true;
|
|
3328
|
+
if (type.isIntersection()) return true;
|
|
3329
|
+
return false;
|
|
3330
|
+
};
|
|
3331
|
+
const enqueueCandidate = (baseDecl, fromTypeAliasRhs) => {
|
|
3332
|
+
if (seen.has(baseDecl)) return;
|
|
3333
|
+
if (ts5.isClassDeclaration(baseDecl) || ts5.isInterfaceDeclaration(baseDecl)) {
|
|
3334
|
+
seen.add(baseDecl);
|
|
3335
|
+
queue.push(baseDecl);
|
|
3336
|
+
return;
|
|
3337
|
+
}
|
|
3338
|
+
if (ts5.isTypeAliasDeclaration(baseDecl)) {
|
|
3339
|
+
if (!fromTypeAliasRhs && !isObjectShapedTypeAlias(baseDecl)) return;
|
|
3340
|
+
seen.add(baseDecl);
|
|
3341
|
+
queue.push(baseDecl);
|
|
3342
|
+
}
|
|
3343
|
+
};
|
|
3344
|
+
const enqueueBasesOf = (decl) => {
|
|
3345
|
+
if (ts5.isTypeAliasDeclaration(decl)) {
|
|
3346
|
+
const rhs = decl.type;
|
|
3347
|
+
if (!ts5.isTypeReferenceNode(rhs)) return;
|
|
3348
|
+
const sym = checker.getSymbolAtLocation(rhs.typeName);
|
|
3349
|
+
if (!sym) return;
|
|
3350
|
+
const target = resolveSymbolTarget(sym);
|
|
3351
|
+
for (const baseDecl of target.declarations ?? []) {
|
|
3352
|
+
enqueueCandidate(
|
|
3353
|
+
baseDecl,
|
|
3354
|
+
/*fromTypeAliasRhs*/
|
|
3355
|
+
true
|
|
3356
|
+
);
|
|
3357
|
+
}
|
|
3358
|
+
return;
|
|
3359
|
+
}
|
|
3360
|
+
const heritageClauses = decl.heritageClauses;
|
|
3361
|
+
if (!heritageClauses) return;
|
|
3362
|
+
for (const clause of heritageClauses) {
|
|
3363
|
+
if (clause.token !== ts5.SyntaxKind.ExtendsKeyword) continue;
|
|
3364
|
+
for (const typeExpr of clause.types) {
|
|
3365
|
+
const sym = checker.getSymbolAtLocation(typeExpr.expression);
|
|
3366
|
+
if (!sym) continue;
|
|
3367
|
+
const target = resolveSymbolTarget(sym);
|
|
3368
|
+
for (const baseDecl of target.declarations ?? []) {
|
|
3369
|
+
enqueueCandidate(
|
|
3370
|
+
baseDecl,
|
|
3371
|
+
/*fromTypeAliasRhs*/
|
|
3372
|
+
false
|
|
3373
|
+
);
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
};
|
|
3378
|
+
enqueueBasesOf(derivedDecl);
|
|
3379
|
+
for (let queueIndex = 0; queueIndex < queue.length && needed.size > 0; queueIndex++) {
|
|
3380
|
+
const baseDecl = queue[queueIndex];
|
|
3381
|
+
if (baseDecl === void 0) continue;
|
|
3382
|
+
const baseFile = baseDecl.getSourceFile().fileName;
|
|
3383
|
+
const baseAnnotations = extractJSDocAnnotationNodes(
|
|
3384
|
+
baseDecl,
|
|
3385
|
+
baseFile,
|
|
3386
|
+
makeParseOptions(extensionRegistry)
|
|
3387
|
+
);
|
|
3388
|
+
for (const annotation of baseAnnotations) {
|
|
3389
|
+
if (!needed.has(annotation.annotationKind)) continue;
|
|
3390
|
+
if (!isOverridingInheritableAnnotation(annotation)) continue;
|
|
3391
|
+
inherited.push(annotation);
|
|
3392
|
+
needed.delete(annotation.annotationKind);
|
|
3393
|
+
}
|
|
3394
|
+
if (needed.size > 0) {
|
|
3395
|
+
enqueueBasesOf(baseDecl);
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
return inherited;
|
|
3399
|
+
}
|
|
3400
|
+
function extractNamedTypeAnnotations(namedDecl, checker, file, extensionRegistry) {
|
|
3401
|
+
const local = extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry));
|
|
3402
|
+
const inherited = collectInheritedTypeAnnotations(namedDecl, local, checker, extensionRegistry);
|
|
3403
|
+
if (inherited.length === 0) return [...local];
|
|
3404
|
+
return [...local, ...inherited];
|
|
3405
|
+
}
|
|
3476
3406
|
function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
3477
3407
|
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
3478
3408
|
const declarationType = checker.getTypeAtLocation(declaration);
|
|
3479
|
-
const logicalName =
|
|
3409
|
+
const logicalName = ts5.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
|
|
3480
3410
|
const docResult = extractJSDocParseResult(
|
|
3481
3411
|
declaration,
|
|
3482
3412
|
file,
|
|
@@ -3518,13 +3448,19 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3518
3448
|
file,
|
|
3519
3449
|
makeParseOptions(extensionRegistry, void 0, checker, classType, classType)
|
|
3520
3450
|
);
|
|
3521
|
-
const
|
|
3451
|
+
const inheritedClassAnnotations = collectInheritedTypeAnnotations(
|
|
3452
|
+
classDecl,
|
|
3453
|
+
classDoc.annotations,
|
|
3454
|
+
checker,
|
|
3455
|
+
extensionRegistry
|
|
3456
|
+
);
|
|
3457
|
+
const annotations = [...classDoc.annotations, ...inheritedClassAnnotations];
|
|
3522
3458
|
diagnostics.push(...classDoc.diagnostics);
|
|
3523
3459
|
const visiting = /* @__PURE__ */ new Set();
|
|
3524
3460
|
const instanceMethods = [];
|
|
3525
3461
|
const staticMethods = [];
|
|
3526
3462
|
for (const member of classDecl.members) {
|
|
3527
|
-
if (
|
|
3463
|
+
if (ts5.isPropertyDeclaration(member)) {
|
|
3528
3464
|
const fieldNode = analyzeFieldToIR(
|
|
3529
3465
|
member,
|
|
3530
3466
|
checker,
|
|
@@ -3540,10 +3476,10 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3540
3476
|
fields.push(fieldNode);
|
|
3541
3477
|
fieldLayouts.push({});
|
|
3542
3478
|
}
|
|
3543
|
-
} else if (
|
|
3479
|
+
} else if (ts5.isMethodDeclaration(member)) {
|
|
3544
3480
|
const methodInfo = analyzeMethod(member, checker);
|
|
3545
3481
|
if (methodInfo) {
|
|
3546
|
-
const isStatic = member.modifiers?.some((m) => m.kind ===
|
|
3482
|
+
const isStatic = member.modifiers?.some((m) => m.kind === ts5.SyntaxKind.StaticKeyword);
|
|
3547
3483
|
if (isStatic) {
|
|
3548
3484
|
staticMethods.push(methodInfo);
|
|
3549
3485
|
} else {
|
|
@@ -3575,6 +3511,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3575
3511
|
hostType: classType
|
|
3576
3512
|
}
|
|
3577
3513
|
);
|
|
3514
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
3578
3515
|
return {
|
|
3579
3516
|
name,
|
|
3580
3517
|
...metadata !== void 0 && { metadata },
|
|
@@ -3582,7 +3519,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3582
3519
|
fieldLayouts,
|
|
3583
3520
|
typeRegistry,
|
|
3584
3521
|
...annotations.length > 0 && { annotations },
|
|
3585
|
-
...
|
|
3522
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
3586
3523
|
instanceMethods,
|
|
3587
3524
|
staticMethods
|
|
3588
3525
|
};
|
|
@@ -3602,11 +3539,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3602
3539
|
file,
|
|
3603
3540
|
makeParseOptions(extensionRegistry, void 0, checker, interfaceType, interfaceType)
|
|
3604
3541
|
);
|
|
3605
|
-
const
|
|
3542
|
+
const inheritedInterfaceAnnotations = collectInheritedTypeAnnotations(
|
|
3543
|
+
interfaceDecl,
|
|
3544
|
+
interfaceDoc.annotations,
|
|
3545
|
+
checker,
|
|
3546
|
+
extensionRegistry
|
|
3547
|
+
);
|
|
3548
|
+
const annotations = [
|
|
3549
|
+
...interfaceDoc.annotations,
|
|
3550
|
+
...inheritedInterfaceAnnotations
|
|
3551
|
+
];
|
|
3606
3552
|
diagnostics.push(...interfaceDoc.diagnostics);
|
|
3607
3553
|
const visiting = /* @__PURE__ */ new Set();
|
|
3608
3554
|
for (const member of interfaceDecl.members) {
|
|
3609
|
-
if (
|
|
3555
|
+
if (ts5.isPropertySignature(member)) {
|
|
3610
3556
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
3611
3557
|
member,
|
|
3612
3558
|
checker,
|
|
@@ -3647,6 +3593,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3647
3593
|
hostType: interfaceType
|
|
3648
3594
|
}
|
|
3649
3595
|
);
|
|
3596
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
3650
3597
|
return {
|
|
3651
3598
|
name,
|
|
3652
3599
|
...metadata !== void 0 && { metadata },
|
|
@@ -3654,7 +3601,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3654
3601
|
fieldLayouts,
|
|
3655
3602
|
typeRegistry,
|
|
3656
3603
|
...annotations.length > 0 && { annotations },
|
|
3657
|
-
...
|
|
3604
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
3658
3605
|
instanceMethods: [],
|
|
3659
3606
|
staticMethods: []
|
|
3660
3607
|
};
|
|
@@ -3664,7 +3611,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3664
3611
|
if (members === null) {
|
|
3665
3612
|
const sourceFile = typeAlias.getSourceFile();
|
|
3666
3613
|
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
3667
|
-
const kindDesc =
|
|
3614
|
+
const kindDesc = ts5.SyntaxKind[typeAlias.type.kind] ?? "unknown";
|
|
3668
3615
|
return {
|
|
3669
3616
|
ok: false,
|
|
3670
3617
|
kind: "not-object-like",
|
|
@@ -3699,7 +3646,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3699
3646
|
diagnostics.push(...typeAliasDoc.diagnostics);
|
|
3700
3647
|
const visiting = /* @__PURE__ */ new Set();
|
|
3701
3648
|
for (const member of members) {
|
|
3702
|
-
if (
|
|
3649
|
+
if (ts5.isPropertySignature(member)) {
|
|
3703
3650
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
3704
3651
|
member,
|
|
3705
3652
|
checker,
|
|
@@ -3739,6 +3686,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3739
3686
|
hostType: aliasType
|
|
3740
3687
|
}
|
|
3741
3688
|
);
|
|
3689
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
3742
3690
|
return {
|
|
3743
3691
|
ok: true,
|
|
3744
3692
|
analysis: {
|
|
@@ -3748,7 +3696,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3748
3696
|
fieldLayouts: specializedFields.map(() => ({})),
|
|
3749
3697
|
typeRegistry,
|
|
3750
3698
|
...annotations.length > 0 && { annotations },
|
|
3751
|
-
...
|
|
3699
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
3752
3700
|
instanceMethods: [],
|
|
3753
3701
|
staticMethods: []
|
|
3754
3702
|
}
|
|
@@ -3766,13 +3714,13 @@ function makeAnalysisDiagnostic(code, message, primaryLocation, relatedLocations
|
|
|
3766
3714
|
function getLeadingParsedTags(node) {
|
|
3767
3715
|
const sourceFile = node.getSourceFile();
|
|
3768
3716
|
const sourceText = sourceFile.getFullText();
|
|
3769
|
-
const commentRanges =
|
|
3717
|
+
const commentRanges = ts5.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
3770
3718
|
if (commentRanges === void 0) {
|
|
3771
3719
|
return [];
|
|
3772
3720
|
}
|
|
3773
3721
|
const parsedTags = [];
|
|
3774
3722
|
for (const range of commentRanges) {
|
|
3775
|
-
if (range.kind !==
|
|
3723
|
+
if (range.kind !== ts5.SyntaxKind.MultiLineCommentTrivia) {
|
|
3776
3724
|
continue;
|
|
3777
3725
|
}
|
|
3778
3726
|
const commentText = sourceText.slice(range.pos, range.end);
|
|
@@ -3790,19 +3738,19 @@ function resolveDiscriminatorProperty(node, checker, fieldName) {
|
|
|
3790
3738
|
return null;
|
|
3791
3739
|
}
|
|
3792
3740
|
const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.find(
|
|
3793
|
-
(candidate) =>
|
|
3741
|
+
(candidate) => ts5.isPropertyDeclaration(candidate) || ts5.isPropertySignature(candidate)
|
|
3794
3742
|
) ?? propertySymbol.declarations?.[0];
|
|
3795
3743
|
return {
|
|
3796
3744
|
declaration,
|
|
3797
3745
|
type: checker.getTypeOfSymbolAtLocation(propertySymbol, declaration ?? node),
|
|
3798
|
-
optional: !!(propertySymbol.flags &
|
|
3746
|
+
optional: !!(propertySymbol.flags & ts5.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
|
|
3799
3747
|
};
|
|
3800
3748
|
}
|
|
3801
3749
|
function isLocalTypeParameterName(node, typeParameterName) {
|
|
3802
3750
|
return node.typeParameters?.some((typeParameter) => typeParameter.name.text === typeParameterName) ?? false;
|
|
3803
3751
|
}
|
|
3804
3752
|
function isNullishSemanticType(type) {
|
|
3805
|
-
if (type.flags & (
|
|
3753
|
+
if (type.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined | ts5.TypeFlags.Void | ts5.TypeFlags.Unknown | ts5.TypeFlags.Any)) {
|
|
3806
3754
|
return true;
|
|
3807
3755
|
}
|
|
3808
3756
|
return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
|
|
@@ -3812,7 +3760,7 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
|
|
|
3812
3760
|
return false;
|
|
3813
3761
|
}
|
|
3814
3762
|
seen.add(type);
|
|
3815
|
-
if (type.flags &
|
|
3763
|
+
if (type.flags & ts5.TypeFlags.StringLike) {
|
|
3816
3764
|
return true;
|
|
3817
3765
|
}
|
|
3818
3766
|
if (type.isUnion()) {
|
|
@@ -3825,13 +3773,13 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
|
|
|
3825
3773
|
return false;
|
|
3826
3774
|
}
|
|
3827
3775
|
function getObjectLikeTypeAliasMembers(typeNode) {
|
|
3828
|
-
if (
|
|
3776
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
3829
3777
|
return getObjectLikeTypeAliasMembers(typeNode.type);
|
|
3830
3778
|
}
|
|
3831
|
-
if (
|
|
3779
|
+
if (ts5.isTypeLiteralNode(typeNode)) {
|
|
3832
3780
|
return [...typeNode.members];
|
|
3833
3781
|
}
|
|
3834
|
-
if (
|
|
3782
|
+
if (ts5.isIntersectionTypeNode(typeNode)) {
|
|
3835
3783
|
const members = [];
|
|
3836
3784
|
for (const intersectionMember of typeNode.types) {
|
|
3837
3785
|
const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
|
|
@@ -3994,7 +3942,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, check
|
|
|
3994
3942
|
}
|
|
3995
3943
|
if (propertyType.isUnion()) {
|
|
3996
3944
|
const nonNullMembers = propertyType.types.filter(
|
|
3997
|
-
(member) => !(member.flags & (
|
|
3945
|
+
(member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
3998
3946
|
);
|
|
3999
3947
|
if (nonNullMembers.length > 0 && nonNullMembers.every((member) => member.isStringLiteral())) {
|
|
4000
3948
|
diagnostics.push(
|
|
@@ -4043,13 +3991,13 @@ function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__
|
|
|
4043
3991
|
seen.add(type);
|
|
4044
3992
|
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
4045
3993
|
if (symbol !== void 0) {
|
|
4046
|
-
const aliased = symbol.flags &
|
|
3994
|
+
const aliased = symbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : void 0;
|
|
4047
3995
|
const targetSymbol = aliased ?? symbol;
|
|
4048
3996
|
const declaration = targetSymbol.declarations?.find(
|
|
4049
|
-
(candidate) =>
|
|
3997
|
+
(candidate) => ts5.isClassDeclaration(candidate) || ts5.isInterfaceDeclaration(candidate) || ts5.isTypeAliasDeclaration(candidate) || ts5.isEnumDeclaration(candidate)
|
|
4050
3998
|
);
|
|
4051
3999
|
if (declaration !== void 0) {
|
|
4052
|
-
if (
|
|
4000
|
+
if (ts5.isTypeAliasDeclaration(declaration) && ts5.isTypeReferenceNode(declaration.type) && checker.getTypeFromTypeNode(declaration.type) !== type) {
|
|
4053
4001
|
return resolveNamedDiscriminatorDeclaration(
|
|
4054
4002
|
checker.getTypeFromTypeNode(declaration.type),
|
|
4055
4003
|
checker,
|
|
@@ -4077,7 +4025,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
|
|
|
4077
4025
|
}
|
|
4078
4026
|
if (boundType.isUnion()) {
|
|
4079
4027
|
const nonNullMembers = boundType.types.filter(
|
|
4080
|
-
(member) => !(member.flags & (
|
|
4028
|
+
(member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
4081
4029
|
);
|
|
4082
4030
|
if (nonNullMembers.every((member) => member.isStringLiteral())) {
|
|
4083
4031
|
diagnostics.push(
|
|
@@ -4122,7 +4070,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
|
|
|
4122
4070
|
return null;
|
|
4123
4071
|
}
|
|
4124
4072
|
function getDeclarationName(node) {
|
|
4125
|
-
if (
|
|
4073
|
+
if (ts5.isClassDeclaration(node) || ts5.isInterfaceDeclaration(node) || ts5.isTypeAliasDeclaration(node) || ts5.isEnumDeclaration(node)) {
|
|
4126
4074
|
return node.name?.text ?? "anonymous";
|
|
4127
4075
|
}
|
|
4128
4076
|
return "anonymous";
|
|
@@ -4177,11 +4125,11 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
4177
4125
|
if (sourceTypeNode === void 0) {
|
|
4178
4126
|
return [];
|
|
4179
4127
|
}
|
|
4180
|
-
const unwrapParentheses = (typeNode) =>
|
|
4128
|
+
const unwrapParentheses = (typeNode) => ts5.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
|
|
4181
4129
|
const directTypeNode = unwrapParentheses(sourceTypeNode);
|
|
4182
|
-
const referenceTypeNode =
|
|
4130
|
+
const referenceTypeNode = ts5.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
|
|
4183
4131
|
const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
|
|
4184
|
-
return
|
|
4132
|
+
return ts5.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
|
|
4185
4133
|
})();
|
|
4186
4134
|
if (referenceTypeNode?.typeArguments === void 0) {
|
|
4187
4135
|
return [];
|
|
@@ -4189,7 +4137,7 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
4189
4137
|
return referenceTypeNode.typeArguments.map((argumentNode) => {
|
|
4190
4138
|
const argumentType = checker.getTypeFromTypeNode(argumentNode);
|
|
4191
4139
|
const baseSymbol = argumentType.aliasSymbol ?? argumentType.getSymbol();
|
|
4192
|
-
const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags &
|
|
4140
|
+
const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(baseSymbol) : baseSymbol;
|
|
4193
4141
|
const argumentDecl = argumentSymbol?.declarations?.[0];
|
|
4194
4142
|
if (argumentDecl !== void 0 && argumentDecl.getSourceFile().fileName !== file) {
|
|
4195
4143
|
const argumentName = argumentSymbol?.getName() ?? baseSymbol?.getName();
|
|
@@ -4252,7 +4200,7 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
|
|
|
4252
4200
|
);
|
|
4253
4201
|
}
|
|
4254
4202
|
function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
4255
|
-
if (!
|
|
4203
|
+
if (!ts5.isIdentifier(prop.name)) {
|
|
4256
4204
|
return null;
|
|
4257
4205
|
}
|
|
4258
4206
|
const name = prop.name.text;
|
|
@@ -4379,7 +4327,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
|
|
|
4379
4327
|
const seen = /* @__PURE__ */ new Set();
|
|
4380
4328
|
const duplicates = /* @__PURE__ */ new Set();
|
|
4381
4329
|
for (const member of members) {
|
|
4382
|
-
if (!
|
|
4330
|
+
if (!ts5.isPropertySignature(member)) {
|
|
4383
4331
|
continue;
|
|
4384
4332
|
}
|
|
4385
4333
|
const name = getAnalyzableObjectLikePropertyName(member.name);
|
|
@@ -4395,7 +4343,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
|
|
|
4395
4343
|
return [...duplicates].sort();
|
|
4396
4344
|
}
|
|
4397
4345
|
function getAnalyzableObjectLikePropertyName(name) {
|
|
4398
|
-
if (
|
|
4346
|
+
if (ts5.isIdentifier(name) || ts5.isStringLiteral(name) || ts5.isNumericLiteral(name)) {
|
|
4399
4347
|
return name.text;
|
|
4400
4348
|
}
|
|
4401
4349
|
return null;
|
|
@@ -4490,28 +4438,28 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
4490
4438
|
if (primitiveAlias) {
|
|
4491
4439
|
return primitiveAlias;
|
|
4492
4440
|
}
|
|
4493
|
-
if (
|
|
4441
|
+
if (_isIntegerBrandedType(type)) {
|
|
4494
4442
|
return { kind: "primitive", primitiveKind: "integer" };
|
|
4495
4443
|
}
|
|
4496
|
-
if (type.flags &
|
|
4444
|
+
if (type.flags & ts5.TypeFlags.String) {
|
|
4497
4445
|
return { kind: "primitive", primitiveKind: "string" };
|
|
4498
4446
|
}
|
|
4499
|
-
if (type.flags &
|
|
4447
|
+
if (type.flags & ts5.TypeFlags.Number) {
|
|
4500
4448
|
return { kind: "primitive", primitiveKind: "number" };
|
|
4501
4449
|
}
|
|
4502
|
-
if (type.flags & (
|
|
4450
|
+
if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
|
|
4503
4451
|
return { kind: "primitive", primitiveKind: "bigint" };
|
|
4504
4452
|
}
|
|
4505
|
-
if (type.flags &
|
|
4453
|
+
if (type.flags & ts5.TypeFlags.Boolean) {
|
|
4506
4454
|
return { kind: "primitive", primitiveKind: "boolean" };
|
|
4507
4455
|
}
|
|
4508
|
-
if (type.flags &
|
|
4456
|
+
if (type.flags & ts5.TypeFlags.Null) {
|
|
4509
4457
|
return { kind: "primitive", primitiveKind: "null" };
|
|
4510
4458
|
}
|
|
4511
|
-
if (type.flags &
|
|
4459
|
+
if (type.flags & ts5.TypeFlags.Undefined) {
|
|
4512
4460
|
return { kind: "primitive", primitiveKind: "null" };
|
|
4513
4461
|
}
|
|
4514
|
-
if (type.flags &
|
|
4462
|
+
if (type.flags & ts5.TypeFlags.Void) {
|
|
4515
4463
|
return { kind: "primitive", primitiveKind: "null" };
|
|
4516
4464
|
}
|
|
4517
4465
|
if (type.isStringLiteral()) {
|
|
@@ -4598,10 +4546,10 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
4598
4546
|
return { kind: "primitive", primitiveKind: "string" };
|
|
4599
4547
|
}
|
|
4600
4548
|
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4601
|
-
if (!(type.flags & (
|
|
4549
|
+
if (!(type.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null)) && !_isIntegerBrandedType(type)) {
|
|
4602
4550
|
return null;
|
|
4603
4551
|
}
|
|
4604
|
-
const aliasDecl = type.aliasSymbol?.declarations?.find(
|
|
4552
|
+
const aliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration) ?? getReferencedTypeAliasDeclaration(sourceNode, checker);
|
|
4605
4553
|
if (!aliasDecl) {
|
|
4606
4554
|
return null;
|
|
4607
4555
|
}
|
|
@@ -4612,11 +4560,18 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
4612
4560
|
...extractJSDocConstraintNodes(aliasDecl, file, makeParseOptions(extensionRegistry)),
|
|
4613
4561
|
...extractTypeAliasConstraintNodes(aliasDecl.type, checker, file, extensionRegistry)
|
|
4614
4562
|
];
|
|
4615
|
-
const
|
|
4563
|
+
const localAnnotations = extractJSDocAnnotationNodes(
|
|
4616
4564
|
aliasDecl,
|
|
4617
4565
|
file,
|
|
4618
4566
|
makeParseOptions(extensionRegistry)
|
|
4619
4567
|
);
|
|
4568
|
+
const inheritedAnnotations = collectInheritedTypeAnnotations(
|
|
4569
|
+
aliasDecl,
|
|
4570
|
+
localAnnotations,
|
|
4571
|
+
checker,
|
|
4572
|
+
extensionRegistry
|
|
4573
|
+
);
|
|
4574
|
+
const annotations = [...localAnnotations, ...inheritedAnnotations];
|
|
4620
4575
|
const metadata = resolveNodeMetadata(
|
|
4621
4576
|
metadataPolicy,
|
|
4622
4577
|
"type",
|
|
@@ -4651,8 +4606,8 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
4651
4606
|
return { kind: "reference", name: aliasName, typeArguments: [] };
|
|
4652
4607
|
}
|
|
4653
4608
|
function getReferencedTypeAliasDeclaration(sourceNode, checker) {
|
|
4654
|
-
const typeNode = sourceNode && (
|
|
4655
|
-
if (!typeNode || !
|
|
4609
|
+
const typeNode = sourceNode && (ts5.isPropertyDeclaration(sourceNode) || ts5.isPropertySignature(sourceNode) || ts5.isParameter(sourceNode)) ? sourceNode.type : void 0;
|
|
4610
|
+
if (!typeNode || !ts5.isTypeReferenceNode(typeNode)) {
|
|
4656
4611
|
return void 0;
|
|
4657
4612
|
}
|
|
4658
4613
|
return getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -4673,7 +4628,7 @@ function resolveNamedTypeWithSourceRecovery(type, sourceNode, checker) {
|
|
|
4673
4628
|
return { typeName: refAliasDecl.name.text, namedDecl: refAliasDecl };
|
|
4674
4629
|
}
|
|
4675
4630
|
function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
4676
|
-
if (!
|
|
4631
|
+
if (!ts5.isTypeReferenceNode(typeNode)) {
|
|
4677
4632
|
return false;
|
|
4678
4633
|
}
|
|
4679
4634
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -4681,10 +4636,10 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
4681
4636
|
return false;
|
|
4682
4637
|
}
|
|
4683
4638
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
4684
|
-
return !!(resolved.flags & (
|
|
4639
|
+
return !!(resolved.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null));
|
|
4685
4640
|
}
|
|
4686
4641
|
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics, visitedAliases = /* @__PURE__ */ new Set()) {
|
|
4687
|
-
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(
|
|
4642
|
+
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration);
|
|
4688
4643
|
if (nestedAliasDecl !== void 0 && !visitedAliases.has(nestedAliasDecl)) {
|
|
4689
4644
|
visitedAliases.add(nestedAliasDecl);
|
|
4690
4645
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -4699,22 +4654,22 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
4699
4654
|
visitedAliases
|
|
4700
4655
|
);
|
|
4701
4656
|
}
|
|
4702
|
-
if (
|
|
4657
|
+
if (_isIntegerBrandedType(type)) {
|
|
4703
4658
|
return { kind: "primitive", primitiveKind: "integer" };
|
|
4704
4659
|
}
|
|
4705
|
-
if (type.flags &
|
|
4660
|
+
if (type.flags & ts5.TypeFlags.String) {
|
|
4706
4661
|
return { kind: "primitive", primitiveKind: "string" };
|
|
4707
4662
|
}
|
|
4708
|
-
if (type.flags &
|
|
4663
|
+
if (type.flags & ts5.TypeFlags.Number) {
|
|
4709
4664
|
return { kind: "primitive", primitiveKind: "number" };
|
|
4710
4665
|
}
|
|
4711
|
-
if (type.flags & (
|
|
4666
|
+
if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
|
|
4712
4667
|
return { kind: "primitive", primitiveKind: "bigint" };
|
|
4713
4668
|
}
|
|
4714
|
-
if (type.flags &
|
|
4669
|
+
if (type.flags & ts5.TypeFlags.Boolean) {
|
|
4715
4670
|
return { kind: "primitive", primitiveKind: "boolean" };
|
|
4716
4671
|
}
|
|
4717
|
-
if (type.flags &
|
|
4672
|
+
if (type.flags & ts5.TypeFlags.Null) {
|
|
4718
4673
|
return { kind: "primitive", primitiveKind: "null" };
|
|
4719
4674
|
}
|
|
4720
4675
|
return resolveTypeNode(
|
|
@@ -4734,7 +4689,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4734
4689
|
let typeName = null;
|
|
4735
4690
|
let namedDecl;
|
|
4736
4691
|
if (recovered !== null) {
|
|
4737
|
-
const recoveredAliasDecl =
|
|
4692
|
+
const recoveredAliasDecl = ts5.isTypeAliasDeclaration(recovered.namedDecl) ? recovered.namedDecl : void 0;
|
|
4738
4693
|
if (recoveredAliasDecl !== void 0) {
|
|
4739
4694
|
const aliasUnderlyingType = checker.getTypeFromTypeNode(recoveredAliasDecl.type);
|
|
4740
4695
|
const isNonGeneric = recoveredAliasDecl.typeParameters === void 0 || recoveredAliasDecl.typeParameters.length === 0;
|
|
@@ -4756,13 +4711,13 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4756
4711
|
(memberTypeNode) => !isNullishTypeNode(resolveAliasedTypeNode(memberTypeNode, checker))
|
|
4757
4712
|
);
|
|
4758
4713
|
const nonNullTypes = allTypes.filter(
|
|
4759
|
-
(memberType) => !(memberType.flags & (
|
|
4714
|
+
(memberType) => !(memberType.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
4760
4715
|
);
|
|
4761
4716
|
const nonNullMembers = nonNullTypes.map((memberType, index) => ({
|
|
4762
4717
|
memberType,
|
|
4763
4718
|
sourceNode: nonNullSourceNodes.length === nonNullTypes.length ? nonNullSourceNodes[index] : void 0
|
|
4764
4719
|
}));
|
|
4765
|
-
const hasNull = allTypes.some((t) => t.flags &
|
|
4720
|
+
const hasNull = allTypes.some((t) => t.flags & ts5.TypeFlags.Null);
|
|
4766
4721
|
const memberDisplayNames = /* @__PURE__ */ new Map();
|
|
4767
4722
|
if (namedDecl) {
|
|
4768
4723
|
for (const [value, label] of extractDisplayNameMetadata(namedDecl).memberDisplayNames) {
|
|
@@ -4782,7 +4737,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4782
4737
|
if (existing !== void 0 && existing.type !== RESOLVING_TYPE_PLACEHOLDER) {
|
|
4783
4738
|
return { kind: "reference", name: typeName, typeArguments: [] };
|
|
4784
4739
|
}
|
|
4785
|
-
const annotations = namedDecl ?
|
|
4740
|
+
const annotations = namedDecl ? extractNamedTypeAnnotations(namedDecl, checker, file, extensionRegistry) : void 0;
|
|
4786
4741
|
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4787
4742
|
metadataPolicy,
|
|
4788
4743
|
"type",
|
|
@@ -4809,7 +4764,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4809
4764
|
const displayName = memberDisplayNames.get(String(value));
|
|
4810
4765
|
return displayName !== void 0 ? { value, displayName } : { value };
|
|
4811
4766
|
});
|
|
4812
|
-
const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags &
|
|
4767
|
+
const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags & ts5.TypeFlags.BooleanLiteral);
|
|
4813
4768
|
if (isBooleanUnion2) {
|
|
4814
4769
|
const boolNode = { kind: "primitive", primitiveKind: "boolean" };
|
|
4815
4770
|
const result = hasNull ? {
|
|
@@ -4901,7 +4856,7 @@ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metad
|
|
|
4901
4856
|
if (type.getProperties().length > 0) {
|
|
4902
4857
|
return null;
|
|
4903
4858
|
}
|
|
4904
|
-
const indexInfo = checker.getIndexInfoOfType(type,
|
|
4859
|
+
const indexInfo = checker.getIndexInfoOfType(type, ts5.IndexKind.String);
|
|
4905
4860
|
if (!indexInfo) {
|
|
4906
4861
|
return null;
|
|
4907
4862
|
}
|
|
@@ -4949,20 +4904,53 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
|
4949
4904
|
}
|
|
4950
4905
|
if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
|
|
4951
4906
|
const name = declaration.name;
|
|
4952
|
-
if (
|
|
4907
|
+
if (ts5.isComputedPropertyName(name) || ts5.isPrivateIdentifier(name)) {
|
|
4953
4908
|
return false;
|
|
4954
4909
|
}
|
|
4955
|
-
if (!
|
|
4910
|
+
if (!ts5.isIdentifier(name) && !ts5.isStringLiteral(name) && !ts5.isNumericLiteral(name)) {
|
|
4956
4911
|
return false;
|
|
4957
4912
|
}
|
|
4958
4913
|
}
|
|
4959
4914
|
return true;
|
|
4960
4915
|
}
|
|
4916
|
+
function getPassThroughTypeAliasFromSourceNode(sourceNode, checker, extensionRegistry, resolvedTypeName) {
|
|
4917
|
+
const aliasDecl = getReferencedTypeAliasDeclaration(sourceNode, checker);
|
|
4918
|
+
if (!aliasDecl) return void 0;
|
|
4919
|
+
const aliasName = aliasDecl.name.text;
|
|
4920
|
+
if (aliasName === resolvedTypeName) return void 0;
|
|
4921
|
+
if (!ts5.isTypeReferenceNode(aliasDecl.type)) return void 0;
|
|
4922
|
+
if (!hasInheritableTypeAnnotation(aliasDecl, checker, extensionRegistry)) {
|
|
4923
|
+
return void 0;
|
|
4924
|
+
}
|
|
4925
|
+
return { aliasName, aliasDecl };
|
|
4926
|
+
}
|
|
4927
|
+
function hasInheritableTypeAnnotation(aliasDecl, checker, extensionRegistry) {
|
|
4928
|
+
const file = aliasDecl.getSourceFile().fileName;
|
|
4929
|
+
const local = extractJSDocAnnotationNodes(aliasDecl, file, makeParseOptions(extensionRegistry));
|
|
4930
|
+
for (const annotation of local) {
|
|
4931
|
+
if (!INHERITABLE_TYPE_ANNOTATION_KINDS.has(annotation.annotationKind)) continue;
|
|
4932
|
+
if (!isOverridingInheritableAnnotation(annotation)) continue;
|
|
4933
|
+
return true;
|
|
4934
|
+
}
|
|
4935
|
+
const inherited = collectInheritedTypeAnnotations(aliasDecl, local, checker, extensionRegistry);
|
|
4936
|
+
for (const annotation of inherited) {
|
|
4937
|
+
if (INHERITABLE_TYPE_ANNOTATION_KINDS.has(annotation.annotationKind)) return true;
|
|
4938
|
+
}
|
|
4939
|
+
return false;
|
|
4940
|
+
}
|
|
4961
4941
|
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4962
4942
|
const collectedDiagnostics = diagnostics ?? [];
|
|
4963
4943
|
const typeName = getNamedTypeName(type);
|
|
4964
4944
|
const namedTypeName = typeName ?? void 0;
|
|
4965
4945
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
4946
|
+
const passThroughAlias = getPassThroughTypeAliasFromSourceNode(
|
|
4947
|
+
sourceNode,
|
|
4948
|
+
checker,
|
|
4949
|
+
extensionRegistry,
|
|
4950
|
+
namedTypeName
|
|
4951
|
+
);
|
|
4952
|
+
const effectiveTypeName = passThroughAlias?.aliasName ?? namedTypeName;
|
|
4953
|
+
const effectiveNamedDecl = passThroughAlias?.aliasDecl ?? namedDecl;
|
|
4966
4954
|
const referenceTypeArguments = extractReferenceTypeArguments(
|
|
4967
4955
|
type,
|
|
4968
4956
|
checker,
|
|
@@ -4974,13 +4962,13 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4974
4962
|
extensionRegistry,
|
|
4975
4963
|
collectedDiagnostics
|
|
4976
4964
|
);
|
|
4977
|
-
const instantiatedTypeName =
|
|
4978
|
-
|
|
4965
|
+
const instantiatedTypeName = effectiveTypeName !== void 0 && referenceTypeArguments.length > 0 ? buildInstantiatedReferenceName(
|
|
4966
|
+
effectiveTypeName,
|
|
4979
4967
|
referenceTypeArguments.map((argument) => argument.tsType),
|
|
4980
4968
|
checker
|
|
4981
4969
|
) : void 0;
|
|
4982
|
-
const registryTypeName = instantiatedTypeName ??
|
|
4983
|
-
const shouldRegisterNamedType = registryTypeName !== void 0 && !(registryTypeName === "Record" &&
|
|
4970
|
+
const registryTypeName = instantiatedTypeName ?? effectiveTypeName;
|
|
4971
|
+
const shouldRegisterNamedType = registryTypeName !== void 0 && !(registryTypeName === "Record" && effectiveNamedDecl?.getSourceFile().fileName !== file);
|
|
4984
4972
|
const clearNamedTypeRegistration = () => {
|
|
4985
4973
|
if (registryTypeName === void 0 || !shouldRegisterNamedType) {
|
|
4986
4974
|
return;
|
|
@@ -5001,7 +4989,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5001
4989
|
typeRegistry[registryTypeName] = {
|
|
5002
4990
|
name: registryTypeName,
|
|
5003
4991
|
type: RESOLVING_TYPE_PLACEHOLDER,
|
|
5004
|
-
provenance: provenanceForDeclaration(
|
|
4992
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
5005
4993
|
};
|
|
5006
4994
|
}
|
|
5007
4995
|
visiting.add(type);
|
|
@@ -5033,17 +5021,17 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5033
5021
|
clearNamedTypeRegistration();
|
|
5034
5022
|
return recordNode;
|
|
5035
5023
|
}
|
|
5036
|
-
const annotations =
|
|
5037
|
-
const metadata =
|
|
5024
|
+
const annotations = effectiveNamedDecl ? extractNamedTypeAnnotations(effectiveNamedDecl, checker, file, extensionRegistry) : void 0;
|
|
5025
|
+
const metadata = effectiveNamedDecl !== void 0 ? resolveNodeMetadata(
|
|
5038
5026
|
metadataPolicy,
|
|
5039
5027
|
"type",
|
|
5040
5028
|
registryTypeName,
|
|
5041
|
-
|
|
5029
|
+
effectiveNamedDecl,
|
|
5042
5030
|
checker,
|
|
5043
5031
|
extensionRegistry,
|
|
5044
5032
|
{
|
|
5045
5033
|
checker,
|
|
5046
|
-
declaration:
|
|
5034
|
+
declaration: effectiveNamedDecl,
|
|
5047
5035
|
subjectType: type
|
|
5048
5036
|
}
|
|
5049
5037
|
) : void 0;
|
|
@@ -5052,7 +5040,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5052
5040
|
...metadata !== void 0 && { metadata },
|
|
5053
5041
|
type: recordNode,
|
|
5054
5042
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
5055
|
-
provenance: provenanceForDeclaration(
|
|
5043
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
5056
5044
|
};
|
|
5057
5045
|
return {
|
|
5058
5046
|
kind: "reference",
|
|
@@ -5078,7 +5066,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5078
5066
|
if (!declaration) continue;
|
|
5079
5067
|
if (!shouldEmitResolvedObjectProperty(prop, declaration)) continue;
|
|
5080
5068
|
const propType = checker.getTypeOfSymbolAtLocation(prop, declaration);
|
|
5081
|
-
const optional = !!(prop.flags &
|
|
5069
|
+
const optional = !!(prop.flags & ts5.SymbolFlags.Optional);
|
|
5082
5070
|
const propTypeNode = resolveTypeNode(
|
|
5083
5071
|
propType,
|
|
5084
5072
|
checker,
|
|
@@ -5091,7 +5079,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5091
5079
|
collectedDiagnostics
|
|
5092
5080
|
);
|
|
5093
5081
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
5094
|
-
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ?
|
|
5082
|
+
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts5.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
|
|
5095
5083
|
declaration,
|
|
5096
5084
|
checker,
|
|
5097
5085
|
file,
|
|
@@ -5101,7 +5089,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5101
5089
|
type,
|
|
5102
5090
|
metadataPolicy,
|
|
5103
5091
|
extensionRegistry
|
|
5104
|
-
) :
|
|
5092
|
+
) : ts5.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
|
|
5105
5093
|
declaration,
|
|
5106
5094
|
checker,
|
|
5107
5095
|
file,
|
|
@@ -5129,9 +5117,9 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5129
5117
|
visiting.delete(type);
|
|
5130
5118
|
const objectNode = {
|
|
5131
5119
|
kind: "object",
|
|
5132
|
-
properties:
|
|
5120
|
+
properties: effectiveNamedDecl !== void 0 && (ts5.isClassDeclaration(effectiveNamedDecl) || ts5.isInterfaceDeclaration(effectiveNamedDecl) || ts5.isTypeAliasDeclaration(effectiveNamedDecl)) ? applyDiscriminatorToObjectProperties(
|
|
5133
5121
|
properties,
|
|
5134
|
-
|
|
5122
|
+
effectiveNamedDecl,
|
|
5135
5123
|
type,
|
|
5136
5124
|
checker,
|
|
5137
5125
|
file,
|
|
@@ -5141,17 +5129,17 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5141
5129
|
additionalProperties: true
|
|
5142
5130
|
};
|
|
5143
5131
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
5144
|
-
const annotations =
|
|
5145
|
-
const metadata =
|
|
5132
|
+
const annotations = effectiveNamedDecl ? extractNamedTypeAnnotations(effectiveNamedDecl, checker, file, extensionRegistry) : void 0;
|
|
5133
|
+
const metadata = effectiveNamedDecl !== void 0 ? resolveNodeMetadata(
|
|
5146
5134
|
metadataPolicy,
|
|
5147
5135
|
"type",
|
|
5148
5136
|
registryTypeName,
|
|
5149
|
-
|
|
5137
|
+
effectiveNamedDecl,
|
|
5150
5138
|
checker,
|
|
5151
5139
|
extensionRegistry,
|
|
5152
5140
|
{
|
|
5153
5141
|
checker,
|
|
5154
|
-
declaration:
|
|
5142
|
+
declaration: effectiveNamedDecl,
|
|
5155
5143
|
subjectType: type
|
|
5156
5144
|
}
|
|
5157
5145
|
) : void 0;
|
|
@@ -5160,7 +5148,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5160
5148
|
...metadata !== void 0 && { metadata },
|
|
5161
5149
|
type: objectNode,
|
|
5162
5150
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
5163
|
-
provenance: provenanceForDeclaration(
|
|
5151
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
5164
5152
|
};
|
|
5165
5153
|
return {
|
|
5166
5154
|
kind: "reference",
|
|
@@ -5177,12 +5165,12 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
5177
5165
|
for (const symbol of symbols) {
|
|
5178
5166
|
const declarations = symbol.declarations;
|
|
5179
5167
|
if (!declarations) continue;
|
|
5180
|
-
const classDecl = declarations.find(
|
|
5168
|
+
const classDecl = declarations.find(ts5.isClassDeclaration);
|
|
5181
5169
|
if (classDecl) {
|
|
5182
5170
|
const map = /* @__PURE__ */ new Map();
|
|
5183
5171
|
const hostType = checker.getTypeAtLocation(classDecl);
|
|
5184
5172
|
for (const member of classDecl.members) {
|
|
5185
|
-
if (
|
|
5173
|
+
if (ts5.isPropertyDeclaration(member) && ts5.isIdentifier(member.name)) {
|
|
5186
5174
|
const fieldNode = analyzeFieldToIR(
|
|
5187
5175
|
member,
|
|
5188
5176
|
checker,
|
|
@@ -5206,7 +5194,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
5206
5194
|
}
|
|
5207
5195
|
return map;
|
|
5208
5196
|
}
|
|
5209
|
-
const interfaceDecl = declarations.find(
|
|
5197
|
+
const interfaceDecl = declarations.find(ts5.isInterfaceDeclaration);
|
|
5210
5198
|
if (interfaceDecl) {
|
|
5211
5199
|
return buildFieldNodeInfoMap(
|
|
5212
5200
|
interfaceDecl.members,
|
|
@@ -5220,7 +5208,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
5220
5208
|
extensionRegistry
|
|
5221
5209
|
);
|
|
5222
5210
|
}
|
|
5223
|
-
const typeAliasDecl = declarations.find(
|
|
5211
|
+
const typeAliasDecl = declarations.find(ts5.isTypeAliasDeclaration);
|
|
5224
5212
|
const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
|
|
5225
5213
|
if (typeAliasDecl && typeAliasMembers !== null) {
|
|
5226
5214
|
return buildFieldNodeInfoMap(
|
|
@@ -5244,10 +5232,10 @@ function extractArrayElementTypeNode(sourceNode, checker) {
|
|
|
5244
5232
|
return void 0;
|
|
5245
5233
|
}
|
|
5246
5234
|
const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
|
|
5247
|
-
if (
|
|
5235
|
+
if (ts5.isArrayTypeNode(resolvedTypeNode)) {
|
|
5248
5236
|
return resolvedTypeNode.elementType;
|
|
5249
5237
|
}
|
|
5250
|
-
if (
|
|
5238
|
+
if (ts5.isTypeReferenceNode(resolvedTypeNode) && ts5.isIdentifier(resolvedTypeNode.typeName) && resolvedTypeNode.typeName.text === "Array" && resolvedTypeNode.typeArguments?.[0]) {
|
|
5251
5239
|
return resolvedTypeNode.typeArguments[0];
|
|
5252
5240
|
}
|
|
5253
5241
|
return void 0;
|
|
@@ -5258,13 +5246,13 @@ function extractUnionMemberTypeNodes(sourceNode, checker) {
|
|
|
5258
5246
|
return [];
|
|
5259
5247
|
}
|
|
5260
5248
|
const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
|
|
5261
|
-
return
|
|
5249
|
+
return ts5.isUnionTypeNode(resolvedTypeNode) ? [...resolvedTypeNode.types] : [];
|
|
5262
5250
|
}
|
|
5263
5251
|
function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new Set()) {
|
|
5264
|
-
if (
|
|
5252
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
5265
5253
|
return resolveAliasedTypeNode(typeNode.type, checker, visited);
|
|
5266
5254
|
}
|
|
5267
|
-
if (!
|
|
5255
|
+
if (!ts5.isTypeReferenceNode(typeNode) || !ts5.isIdentifier(typeNode.typeName)) {
|
|
5268
5256
|
return typeNode;
|
|
5269
5257
|
}
|
|
5270
5258
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -5275,15 +5263,15 @@ function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new
|
|
|
5275
5263
|
return resolveAliasedTypeNode(aliasDecl.type, checker, visited);
|
|
5276
5264
|
}
|
|
5277
5265
|
function isNullishTypeNode(typeNode) {
|
|
5278
|
-
if (typeNode.kind ===
|
|
5266
|
+
if (typeNode.kind === ts5.SyntaxKind.NullKeyword || typeNode.kind === ts5.SyntaxKind.UndefinedKeyword) {
|
|
5279
5267
|
return true;
|
|
5280
5268
|
}
|
|
5281
|
-
return
|
|
5269
|
+
return ts5.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts5.SyntaxKind.NullKeyword || typeNode.literal.kind === ts5.SyntaxKind.UndefinedKeyword);
|
|
5282
5270
|
}
|
|
5283
5271
|
function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, metadataPolicy, hostType, diagnostics, extensionRegistry) {
|
|
5284
5272
|
const map = /* @__PURE__ */ new Map();
|
|
5285
5273
|
for (const member of members) {
|
|
5286
|
-
if (
|
|
5274
|
+
if (ts5.isPropertySignature(member)) {
|
|
5287
5275
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
5288
5276
|
member,
|
|
5289
5277
|
checker,
|
|
@@ -5309,7 +5297,7 @@ function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, m
|
|
|
5309
5297
|
}
|
|
5310
5298
|
var MAX_ALIAS_CHAIN_DEPTH = 8;
|
|
5311
5299
|
function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegistry, depth = 0) {
|
|
5312
|
-
if (!
|
|
5300
|
+
if (!ts5.isTypeReferenceNode(typeNode)) return [];
|
|
5313
5301
|
if (depth >= MAX_ALIAS_CHAIN_DEPTH) {
|
|
5314
5302
|
const aliasName = typeNode.typeName.getText();
|
|
5315
5303
|
throw new Error(
|
|
@@ -5318,7 +5306,7 @@ function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegis
|
|
|
5318
5306
|
}
|
|
5319
5307
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
5320
5308
|
if (!aliasDecl) return [];
|
|
5321
|
-
if (
|
|
5309
|
+
if (ts5.isTypeLiteralNode(aliasDecl.type)) return [];
|
|
5322
5310
|
const aliasFieldType = resolveTypeNode(
|
|
5323
5311
|
checker.getTypeAtLocation(aliasDecl.type),
|
|
5324
5312
|
checker,
|
|
@@ -5362,14 +5350,14 @@ function getNamedTypeName(type) {
|
|
|
5362
5350
|
const symbol = type.getSymbol();
|
|
5363
5351
|
if (symbol?.declarations) {
|
|
5364
5352
|
const decl = symbol.declarations[0];
|
|
5365
|
-
if (decl && (
|
|
5366
|
-
const name =
|
|
5353
|
+
if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
|
|
5354
|
+
const name = ts5.isClassDeclaration(decl) ? decl.name?.text : decl.name.text;
|
|
5367
5355
|
if (name) return name;
|
|
5368
5356
|
}
|
|
5369
5357
|
}
|
|
5370
5358
|
const aliasSymbol = type.aliasSymbol;
|
|
5371
5359
|
if (aliasSymbol?.declarations) {
|
|
5372
|
-
const aliasDecl = aliasSymbol.declarations.find(
|
|
5360
|
+
const aliasDecl = aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
|
|
5373
5361
|
if (aliasDecl) {
|
|
5374
5362
|
return aliasDecl.name.text;
|
|
5375
5363
|
}
|
|
@@ -5380,24 +5368,24 @@ function getNamedTypeDeclaration(type) {
|
|
|
5380
5368
|
const symbol = type.getSymbol();
|
|
5381
5369
|
if (symbol?.declarations) {
|
|
5382
5370
|
const decl = symbol.declarations[0];
|
|
5383
|
-
if (decl && (
|
|
5371
|
+
if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
|
|
5384
5372
|
return decl;
|
|
5385
5373
|
}
|
|
5386
5374
|
}
|
|
5387
5375
|
const aliasSymbol = type.aliasSymbol;
|
|
5388
5376
|
if (aliasSymbol?.declarations) {
|
|
5389
|
-
return aliasSymbol.declarations.find(
|
|
5377
|
+
return aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
|
|
5390
5378
|
}
|
|
5391
5379
|
return void 0;
|
|
5392
5380
|
}
|
|
5393
5381
|
function analyzeMethod(method, checker) {
|
|
5394
|
-
if (!
|
|
5382
|
+
if (!ts5.isIdentifier(method.name)) {
|
|
5395
5383
|
return null;
|
|
5396
5384
|
}
|
|
5397
5385
|
const name = method.name.text;
|
|
5398
5386
|
const parameters = [];
|
|
5399
5387
|
for (const param of method.parameters) {
|
|
5400
|
-
if (
|
|
5388
|
+
if (ts5.isIdentifier(param.name)) {
|
|
5401
5389
|
const paramInfo = analyzeParameter(param, checker);
|
|
5402
5390
|
parameters.push(paramInfo);
|
|
5403
5391
|
}
|
|
@@ -5408,7 +5396,7 @@ function analyzeMethod(method, checker) {
|
|
|
5408
5396
|
return { name, parameters, returnTypeNode, returnType };
|
|
5409
5397
|
}
|
|
5410
5398
|
function analyzeParameter(param, checker) {
|
|
5411
|
-
const name =
|
|
5399
|
+
const name = ts5.isIdentifier(param.name) ? param.name.text : "param";
|
|
5412
5400
|
const typeNode = param.type;
|
|
5413
5401
|
const type = checker.getTypeAtLocation(param);
|
|
5414
5402
|
const formSpecExportName = detectFormSpecReference(typeNode);
|
|
@@ -5417,15 +5405,15 @@ function analyzeParameter(param, checker) {
|
|
|
5417
5405
|
}
|
|
5418
5406
|
function detectFormSpecReference(typeNode) {
|
|
5419
5407
|
if (!typeNode) return null;
|
|
5420
|
-
if (!
|
|
5421
|
-
const typeName =
|
|
5408
|
+
if (!ts5.isTypeReferenceNode(typeNode)) return null;
|
|
5409
|
+
const typeName = ts5.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : ts5.isQualifiedName(typeNode.typeName) ? typeNode.typeName.right.text : null;
|
|
5422
5410
|
if (typeName !== "InferSchema" && typeName !== "InferFormSchema") return null;
|
|
5423
5411
|
const typeArg = typeNode.typeArguments?.[0];
|
|
5424
|
-
if (!typeArg || !
|
|
5425
|
-
if (
|
|
5412
|
+
if (!typeArg || !ts5.isTypeQueryNode(typeArg)) return null;
|
|
5413
|
+
if (ts5.isIdentifier(typeArg.exprName)) {
|
|
5426
5414
|
return typeArg.exprName.text;
|
|
5427
5415
|
}
|
|
5428
|
-
if (
|
|
5416
|
+
if (ts5.isQualifiedName(typeArg.exprName)) {
|
|
5429
5417
|
return typeArg.exprName.right.text;
|
|
5430
5418
|
}
|
|
5431
5419
|
return null;
|
|
@@ -5447,23 +5435,23 @@ function createProgramContextFromProgram(program, filePath) {
|
|
|
5447
5435
|
function createProgramContext(filePath, additionalFiles) {
|
|
5448
5436
|
const absolutePath = path.resolve(filePath);
|
|
5449
5437
|
const fileDir = path.dirname(absolutePath);
|
|
5450
|
-
const configPath =
|
|
5438
|
+
const configPath = ts6.findConfigFile(fileDir, ts6.sys.fileExists.bind(ts6.sys), "tsconfig.json");
|
|
5451
5439
|
let compilerOptions;
|
|
5452
5440
|
let fileNames;
|
|
5453
5441
|
if (configPath) {
|
|
5454
|
-
const configFile =
|
|
5442
|
+
const configFile = ts6.readConfigFile(configPath, ts6.sys.readFile.bind(ts6.sys));
|
|
5455
5443
|
if (configFile.error) {
|
|
5456
5444
|
throw new Error(
|
|
5457
|
-
`Error reading tsconfig.json: ${
|
|
5445
|
+
`Error reading tsconfig.json: ${ts6.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
|
|
5458
5446
|
);
|
|
5459
5447
|
}
|
|
5460
|
-
const parsed =
|
|
5448
|
+
const parsed = ts6.parseJsonConfigFileContent(
|
|
5461
5449
|
configFile.config,
|
|
5462
|
-
|
|
5450
|
+
ts6.sys,
|
|
5463
5451
|
path.dirname(configPath)
|
|
5464
5452
|
);
|
|
5465
5453
|
if (parsed.errors.length > 0) {
|
|
5466
|
-
const errorMessages = parsed.errors.map((e) =>
|
|
5454
|
+
const errorMessages = parsed.errors.map((e) => ts6.flattenDiagnosticMessageText(e.messageText, "\n")).join("\n");
|
|
5467
5455
|
throw new Error(`Error parsing tsconfig.json: ${errorMessages}`);
|
|
5468
5456
|
}
|
|
5469
5457
|
compilerOptions = parsed.options;
|
|
@@ -5471,9 +5459,9 @@ function createProgramContext(filePath, additionalFiles) {
|
|
|
5471
5459
|
fileNames = [.../* @__PURE__ */ new Set([...parsed.fileNames, absolutePath, ...normalizedAdditional])];
|
|
5472
5460
|
} else {
|
|
5473
5461
|
compilerOptions = {
|
|
5474
|
-
target:
|
|
5475
|
-
module:
|
|
5476
|
-
moduleResolution:
|
|
5462
|
+
target: ts6.ScriptTarget.ES2022,
|
|
5463
|
+
module: ts6.ModuleKind.NodeNext,
|
|
5464
|
+
moduleResolution: ts6.ModuleResolutionKind.NodeNext,
|
|
5477
5465
|
strict: true,
|
|
5478
5466
|
skipLibCheck: true,
|
|
5479
5467
|
declaration: true
|
|
@@ -5481,7 +5469,7 @@ function createProgramContext(filePath, additionalFiles) {
|
|
|
5481
5469
|
const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
|
|
5482
5470
|
fileNames = [.../* @__PURE__ */ new Set([absolutePath, ...normalizedAdditional])];
|
|
5483
5471
|
}
|
|
5484
|
-
const program =
|
|
5472
|
+
const program = ts6.createProgram(fileNames, compilerOptions);
|
|
5485
5473
|
const sourceFile = program.getSourceFile(absolutePath);
|
|
5486
5474
|
if (!sourceFile) {
|
|
5487
5475
|
throw new Error(`Could not find source file: ${absolutePath}`);
|
|
@@ -5500,19 +5488,19 @@ function findNodeByName(sourceFile, name, predicate, getName) {
|
|
|
5500
5488
|
result = node;
|
|
5501
5489
|
return;
|
|
5502
5490
|
}
|
|
5503
|
-
|
|
5491
|
+
ts6.forEachChild(node, visit);
|
|
5504
5492
|
}
|
|
5505
5493
|
visit(sourceFile);
|
|
5506
5494
|
return result;
|
|
5507
5495
|
}
|
|
5508
5496
|
function findClassByName(sourceFile, className) {
|
|
5509
|
-
return findNodeByName(sourceFile, className,
|
|
5497
|
+
return findNodeByName(sourceFile, className, ts6.isClassDeclaration, (n) => n.name?.text);
|
|
5510
5498
|
}
|
|
5511
5499
|
function findInterfaceByName(sourceFile, interfaceName) {
|
|
5512
|
-
return findNodeByName(sourceFile, interfaceName,
|
|
5500
|
+
return findNodeByName(sourceFile, interfaceName, ts6.isInterfaceDeclaration, (n) => n.name.text);
|
|
5513
5501
|
}
|
|
5514
5502
|
function findTypeAliasByName(sourceFile, aliasName) {
|
|
5515
|
-
return findNodeByName(sourceFile, aliasName,
|
|
5503
|
+
return findNodeByName(sourceFile, aliasName, ts6.isTypeAliasDeclaration, (n) => n.name.text);
|
|
5516
5504
|
}
|
|
5517
5505
|
function getResolvedObjectRootType(rootType, typeRegistry) {
|
|
5518
5506
|
if (rootType.kind === "object") {
|
|
@@ -5552,22 +5540,22 @@ function createResolvedObjectAliasAnalysis(name, rootType, typeRegistry, rootInf
|
|
|
5552
5540
|
};
|
|
5553
5541
|
}
|
|
5554
5542
|
function containsTypeReferenceInObjectLikeAlias(typeNode) {
|
|
5555
|
-
if (
|
|
5543
|
+
if (ts6.isParenthesizedTypeNode(typeNode)) {
|
|
5556
5544
|
return containsTypeReferenceInObjectLikeAlias(typeNode.type);
|
|
5557
5545
|
}
|
|
5558
|
-
if (
|
|
5546
|
+
if (ts6.isTypeReferenceNode(typeNode)) {
|
|
5559
5547
|
return true;
|
|
5560
5548
|
}
|
|
5561
|
-
return
|
|
5549
|
+
return ts6.isIntersectionTypeNode(typeNode) && typeNode.types.some((member) => containsTypeReferenceInObjectLikeAlias(member));
|
|
5562
5550
|
}
|
|
5563
5551
|
function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
|
|
5564
|
-
if (
|
|
5552
|
+
if (ts6.isParenthesizedTypeNode(typeNode)) {
|
|
5565
5553
|
return collectFallbackAliasMemberPropertyNames(typeNode.type, checker);
|
|
5566
5554
|
}
|
|
5567
|
-
if (
|
|
5555
|
+
if (ts6.isTypeLiteralNode(typeNode)) {
|
|
5568
5556
|
const propertyNames = [];
|
|
5569
5557
|
for (const member of typeNode.members) {
|
|
5570
|
-
if (!
|
|
5558
|
+
if (!ts6.isPropertySignature(member)) {
|
|
5571
5559
|
continue;
|
|
5572
5560
|
}
|
|
5573
5561
|
const propertyName = getAnalyzableObjectLikePropertyName(member.name);
|
|
@@ -5577,13 +5565,13 @@ function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
|
|
|
5577
5565
|
}
|
|
5578
5566
|
return propertyNames;
|
|
5579
5567
|
}
|
|
5580
|
-
if (
|
|
5568
|
+
if (ts6.isTypeReferenceNode(typeNode)) {
|
|
5581
5569
|
return checker.getTypeFromTypeNode(typeNode).getProperties().map((property) => property.getName());
|
|
5582
5570
|
}
|
|
5583
5571
|
return null;
|
|
5584
5572
|
}
|
|
5585
5573
|
function findFallbackAliasDuplicatePropertyNames(typeNode, checker) {
|
|
5586
|
-
if (!
|
|
5574
|
+
if (!ts6.isIntersectionTypeNode(typeNode)) {
|
|
5587
5575
|
return [];
|
|
5588
5576
|
}
|
|
5589
5577
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -5784,7 +5772,7 @@ function makeFileProvenance(filePath) {
|
|
|
5784
5772
|
}
|
|
5785
5773
|
|
|
5786
5774
|
// src/extensions/symbol-registry.ts
|
|
5787
|
-
import * as
|
|
5775
|
+
import * as ts7 from "typescript";
|
|
5788
5776
|
import * as path2 from "path";
|
|
5789
5777
|
function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistry) {
|
|
5790
5778
|
const symbolMap = /* @__PURE__ */ new Map();
|
|
@@ -5794,10 +5782,10 @@ function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistr
|
|
|
5794
5782
|
return symbolMap;
|
|
5795
5783
|
}
|
|
5796
5784
|
function visit(node) {
|
|
5797
|
-
if (
|
|
5785
|
+
if (ts7.isCallExpression(node) && isDefineCustomTypeCall(node, checker)) {
|
|
5798
5786
|
processDefineCustomTypeCall(node);
|
|
5799
5787
|
}
|
|
5800
|
-
|
|
5788
|
+
ts7.forEachChild(node, visit);
|
|
5801
5789
|
}
|
|
5802
5790
|
function processDefineCustomTypeCall(call) {
|
|
5803
5791
|
const typeArgNode = call.typeArguments?.[0];
|
|
@@ -5834,7 +5822,7 @@ function isDefineCustomTypeCall(node, checker) {
|
|
|
5834
5822
|
if (node.typeArguments === void 0 || node.typeArguments.length === 0) return false;
|
|
5835
5823
|
const callSymbol = checker.getSymbolAtLocation(node.expression);
|
|
5836
5824
|
if (callSymbol !== void 0) {
|
|
5837
|
-
const resolved = callSymbol.flags &
|
|
5825
|
+
const resolved = callSymbol.flags & ts7.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
|
|
5838
5826
|
const decl = resolved.declarations?.[0];
|
|
5839
5827
|
if (decl !== void 0) {
|
|
5840
5828
|
const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
|
|
@@ -5842,24 +5830,24 @@ function isDefineCustomTypeCall(node, checker) {
|
|
|
5842
5830
|
(sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
|
|
5843
5831
|
}
|
|
5844
5832
|
}
|
|
5845
|
-
return
|
|
5833
|
+
return ts7.isIdentifier(node.expression) && node.expression.text === "defineCustomType";
|
|
5846
5834
|
}
|
|
5847
5835
|
function extractTypeNameFromCallArg(call) {
|
|
5848
5836
|
const arg = call.arguments[0];
|
|
5849
|
-
if (arg === void 0 || !
|
|
5837
|
+
if (arg === void 0 || !ts7.isObjectLiteralExpression(arg)) {
|
|
5850
5838
|
return null;
|
|
5851
5839
|
}
|
|
5852
5840
|
const typeNameProp = arg.properties.find(
|
|
5853
|
-
(p) =>
|
|
5841
|
+
(p) => ts7.isPropertyAssignment(p) && ts7.isIdentifier(p.name) && p.name.text === "typeName"
|
|
5854
5842
|
);
|
|
5855
|
-
if (typeNameProp === void 0 || !
|
|
5843
|
+
if (typeNameProp === void 0 || !ts7.isStringLiteral(typeNameProp.initializer)) {
|
|
5856
5844
|
return null;
|
|
5857
5845
|
}
|
|
5858
5846
|
return typeNameProp.initializer.text;
|
|
5859
5847
|
}
|
|
5860
5848
|
function extractEnclosingExtensionId(call, checker) {
|
|
5861
|
-
for (let node = call.parent; !
|
|
5862
|
-
if (
|
|
5849
|
+
for (let node = call.parent; !ts7.isSourceFile(node); node = node.parent) {
|
|
5850
|
+
if (ts7.isCallExpression(node) && isDefineExtensionCall(node, checker)) {
|
|
5863
5851
|
return extractExtensionIdFromCallArg(node);
|
|
5864
5852
|
}
|
|
5865
5853
|
}
|
|
@@ -5868,24 +5856,24 @@ function extractEnclosingExtensionId(call, checker) {
|
|
|
5868
5856
|
function isDefineExtensionCall(node, checker) {
|
|
5869
5857
|
const callSymbol = checker.getSymbolAtLocation(node.expression);
|
|
5870
5858
|
if (callSymbol !== void 0) {
|
|
5871
|
-
const resolved = callSymbol.flags &
|
|
5859
|
+
const resolved = callSymbol.flags & ts7.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
|
|
5872
5860
|
const decl = resolved.declarations?.[0];
|
|
5873
5861
|
if (decl !== void 0) {
|
|
5874
5862
|
const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
|
|
5875
5863
|
return resolved.name === "defineExtension" && (sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
|
|
5876
5864
|
}
|
|
5877
5865
|
}
|
|
5878
|
-
return
|
|
5866
|
+
return ts7.isIdentifier(node.expression) && node.expression.text === "defineExtension";
|
|
5879
5867
|
}
|
|
5880
5868
|
function extractExtensionIdFromCallArg(call) {
|
|
5881
5869
|
const arg = call.arguments[0];
|
|
5882
|
-
if (arg === void 0 || !
|
|
5870
|
+
if (arg === void 0 || !ts7.isObjectLiteralExpression(arg)) {
|
|
5883
5871
|
return null;
|
|
5884
5872
|
}
|
|
5885
5873
|
const prop = arg.properties.find(
|
|
5886
|
-
(p) =>
|
|
5874
|
+
(p) => ts7.isPropertyAssignment(p) && ts7.isIdentifier(p.name) && p.name.text === "extensionId"
|
|
5887
5875
|
);
|
|
5888
|
-
if (prop === void 0 || !
|
|
5876
|
+
if (prop === void 0 || !ts7.isStringLiteral(prop.initializer)) {
|
|
5889
5877
|
return null;
|
|
5890
5878
|
}
|
|
5891
5879
|
return prop.initializer.text;
|
|
@@ -6147,7 +6135,7 @@ function generateSchemasBatch(options) {
|
|
|
6147
6135
|
return options.targets.map((target) => {
|
|
6148
6136
|
let ctx;
|
|
6149
6137
|
try {
|
|
6150
|
-
const cacheKey =
|
|
6138
|
+
const cacheKey = ts8.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
|
|
6151
6139
|
const cachedContext = contextCache.get(cacheKey);
|
|
6152
6140
|
if (cachedContext === void 0) {
|
|
6153
6141
|
const additionalFiles = options.configPath !== void 0 ? [options.configPath] : void 0;
|
|
@@ -6206,7 +6194,7 @@ function isMutableRegistry(reg) {
|
|
|
6206
6194
|
}
|
|
6207
6195
|
function resolveStaticOptions(options) {
|
|
6208
6196
|
const legacyRegistry = options.extensionRegistry;
|
|
6209
|
-
const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6197
|
+
const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 && options.config.extensions.length > 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6210
6198
|
return {
|
|
6211
6199
|
extensionRegistry: legacyRegistry ?? configRegistry,
|
|
6212
6200
|
// eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
|
|
@@ -6218,7 +6206,7 @@ function resolveStaticOptions(options) {
|
|
|
6218
6206
|
};
|
|
6219
6207
|
}
|
|
6220
6208
|
function resolveOptions(options) {
|
|
6221
|
-
const configRegistry = options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6209
|
+
const configRegistry = options.config?.extensions !== void 0 && options.config.extensions.length > 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6222
6210
|
const legacyRegistry = options.extensionRegistry;
|
|
6223
6211
|
return {
|
|
6224
6212
|
// When the caller provides the deprecated extensionRegistry field directly,
|
|
@@ -6303,7 +6291,7 @@ function createProgramContextFailureDiagnostic(filePath, error) {
|
|
|
6303
6291
|
}
|
|
6304
6292
|
|
|
6305
6293
|
// src/static-build.ts
|
|
6306
|
-
import * as
|
|
6294
|
+
import * as ts9 from "typescript";
|
|
6307
6295
|
function toStaticBuildContext(context) {
|
|
6308
6296
|
return context;
|
|
6309
6297
|
}
|
|
@@ -6318,7 +6306,7 @@ function getModuleSymbol(context) {
|
|
|
6318
6306
|
return context.checker.getSymbolAtLocation(context.sourceFile) ?? sourceFileWithSymbol.symbol;
|
|
6319
6307
|
}
|
|
6320
6308
|
function isSchemaSourceDeclaration(declaration) {
|
|
6321
|
-
return
|
|
6309
|
+
return ts9.isClassDeclaration(declaration) || ts9.isInterfaceDeclaration(declaration) || ts9.isTypeAliasDeclaration(declaration);
|
|
6322
6310
|
}
|
|
6323
6311
|
function resolveModuleExport(context, exportName = "default") {
|
|
6324
6312
|
const moduleSymbol = getModuleSymbol(context);
|
|
@@ -6329,14 +6317,14 @@ function resolveModuleExport(context, exportName = "default") {
|
|
|
6329
6317
|
if (exportSymbol === null) {
|
|
6330
6318
|
return null;
|
|
6331
6319
|
}
|
|
6332
|
-
return exportSymbol.flags &
|
|
6320
|
+
return exportSymbol.flags & ts9.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
|
|
6333
6321
|
}
|
|
6334
6322
|
function resolveModuleExportDeclaration(context, exportName = "default") {
|
|
6335
6323
|
return resolveModuleExport(context, exportName)?.declarations?.find(isSchemaSourceDeclaration) ?? null;
|
|
6336
6324
|
}
|
|
6337
6325
|
|
|
6338
6326
|
// src/generators/discovered-schema.ts
|
|
6339
|
-
import * as
|
|
6327
|
+
import * as ts10 from "typescript";
|
|
6340
6328
|
import { analyzeMetadataForNodeWithChecker as analyzeMetadataForNodeWithChecker2 } from "@formspec/analysis/internal";
|
|
6341
6329
|
import { IR_VERSION as IR_VERSION3 } from "@formspec/core/internals";
|
|
6342
6330
|
function toDiscoveredTypeSchemas(result, resolvedMetadata) {
|
|
@@ -6346,17 +6334,17 @@ function toDiscoveredTypeSchemas(result, resolvedMetadata) {
|
|
|
6346
6334
|
};
|
|
6347
6335
|
}
|
|
6348
6336
|
function isNamedTypeDeclaration(declaration) {
|
|
6349
|
-
return
|
|
6337
|
+
return ts10.isClassDeclaration(declaration) || ts10.isInterfaceDeclaration(declaration) || ts10.isTypeAliasDeclaration(declaration);
|
|
6350
6338
|
}
|
|
6351
6339
|
function hasConcreteTypeArguments(type, checker) {
|
|
6352
6340
|
if ("aliasTypeArguments" in type && Array.isArray(type.aliasTypeArguments) && type.aliasTypeArguments.length > 0) {
|
|
6353
6341
|
return true;
|
|
6354
6342
|
}
|
|
6355
|
-
if ((type.flags &
|
|
6343
|
+
if ((type.flags & ts10.TypeFlags.Object) === 0) {
|
|
6356
6344
|
return false;
|
|
6357
6345
|
}
|
|
6358
6346
|
const objectType = type;
|
|
6359
|
-
if ((objectType.objectFlags &
|
|
6347
|
+
if ((objectType.objectFlags & ts10.ObjectFlags.Reference) === 0) {
|
|
6360
6348
|
return false;
|
|
6361
6349
|
}
|
|
6362
6350
|
return checker.getTypeArguments(objectType).length > 0;
|
|
@@ -6369,13 +6357,13 @@ function getNamedTypeDeclaration2(type) {
|
|
|
6369
6357
|
return declaration;
|
|
6370
6358
|
}
|
|
6371
6359
|
}
|
|
6372
|
-
const aliasDeclaration = type.aliasSymbol?.declarations?.find(
|
|
6360
|
+
const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts10.isTypeAliasDeclaration);
|
|
6373
6361
|
return aliasDeclaration;
|
|
6374
6362
|
}
|
|
6375
6363
|
function getFallbackName(sourceNode, fallback = "AnonymousType") {
|
|
6376
6364
|
if (sourceNode !== void 0 && "name" in sourceNode) {
|
|
6377
6365
|
const namedNode = sourceNode;
|
|
6378
|
-
if (namedNode.name !== void 0 &&
|
|
6366
|
+
if (namedNode.name !== void 0 && ts10.isIdentifier(namedNode.name)) {
|
|
6379
6367
|
return namedNode.name.text;
|
|
6380
6368
|
}
|
|
6381
6369
|
}
|
|
@@ -6597,7 +6585,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
|
|
|
6597
6585
|
function generateSchemasFromDeclaration(options) {
|
|
6598
6586
|
const filePath = options.declaration.getSourceFile().fileName;
|
|
6599
6587
|
const resolved = resolveStaticOptions(options);
|
|
6600
|
-
if (
|
|
6588
|
+
if (ts10.isClassDeclaration(options.declaration)) {
|
|
6601
6589
|
return generateSchemasFromAnalysis(
|
|
6602
6590
|
analyzeClassToIR(
|
|
6603
6591
|
options.declaration,
|
|
@@ -6611,7 +6599,7 @@ function generateSchemasFromDeclaration(options) {
|
|
|
6611
6599
|
resolved
|
|
6612
6600
|
);
|
|
6613
6601
|
}
|
|
6614
|
-
if (
|
|
6602
|
+
if (ts10.isInterfaceDeclaration(options.declaration)) {
|
|
6615
6603
|
return generateSchemasFromAnalysis(
|
|
6616
6604
|
analyzeInterfaceToIR(
|
|
6617
6605
|
options.declaration,
|
|
@@ -6625,7 +6613,7 @@ function generateSchemasFromDeclaration(options) {
|
|
|
6625
6613
|
resolved
|
|
6626
6614
|
);
|
|
6627
6615
|
}
|
|
6628
|
-
if (
|
|
6616
|
+
if (ts10.isTypeAliasDeclaration(options.declaration)) {
|
|
6629
6617
|
const analyzedAlias = analyzeTypeAliasToIR(
|
|
6630
6618
|
options.declaration,
|
|
6631
6619
|
options.context.checker,
|
|
@@ -6684,7 +6672,7 @@ function generateSchemasFromReturnType(options) {
|
|
|
6684
6672
|
const returnType = signature !== void 0 ? options.context.checker.getReturnTypeOfSignature(signature) : options.context.checker.getTypeAtLocation(options.declaration);
|
|
6685
6673
|
const type = unwrapPromiseType(options.context.checker, returnType);
|
|
6686
6674
|
const sourceNode = type !== returnType ? unwrapPromiseTypeNode(options.declaration.type) ?? options.declaration.type ?? options.declaration : options.declaration.type ?? options.declaration;
|
|
6687
|
-
const fallbackName = options.declaration.name !== void 0 &&
|
|
6675
|
+
const fallbackName = options.declaration.name !== void 0 && ts10.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
|
|
6688
6676
|
return generateSchemasFromResolvedType({
|
|
6689
6677
|
...options,
|
|
6690
6678
|
type,
|
|
@@ -6731,14 +6719,14 @@ function unwrapPromiseTypeNode(typeNode) {
|
|
|
6731
6719
|
if (typeNode === void 0) {
|
|
6732
6720
|
return void 0;
|
|
6733
6721
|
}
|
|
6734
|
-
if (
|
|
6722
|
+
if (ts10.isParenthesizedTypeNode(typeNode)) {
|
|
6735
6723
|
const unwrapped = unwrapPromiseTypeNode(typeNode.type);
|
|
6736
6724
|
return unwrapped ?? typeNode;
|
|
6737
6725
|
}
|
|
6738
6726
|
return isPromiseTypeReferenceNode(typeNode) ? typeNode.typeArguments[0] : typeNode;
|
|
6739
6727
|
}
|
|
6740
6728
|
function isPromiseTypeReferenceNode(typeNode) {
|
|
6741
|
-
return
|
|
6729
|
+
return ts10.isTypeReferenceNode(typeNode) && ts10.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
|
|
6742
6730
|
}
|
|
6743
6731
|
|
|
6744
6732
|
// src/generators/mixed-authoring.ts
|