@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/cli.js
CHANGED
|
@@ -1048,7 +1048,7 @@ function generateJsonSchemaFromIR(ir, options) {
|
|
|
1048
1048
|
applyConstraints(ctx.defs[schemaName], typeDef.constraints, ctx);
|
|
1049
1049
|
}
|
|
1050
1050
|
if (typeDef.annotations && typeDef.annotations.length > 0) {
|
|
1051
|
-
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx);
|
|
1051
|
+
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx, typeDef.type);
|
|
1052
1052
|
}
|
|
1053
1053
|
}
|
|
1054
1054
|
const properties = {};
|
|
@@ -1121,7 +1121,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
1121
1121
|
}
|
|
1122
1122
|
}
|
|
1123
1123
|
applyResolvedMetadata(schema, field.metadata);
|
|
1124
|
-
applyAnnotations(schema, rootAnnotations, ctx);
|
|
1124
|
+
applyAnnotations(schema, rootAnnotations, ctx, field.type);
|
|
1125
1125
|
if (itemStringSchema !== void 0) {
|
|
1126
1126
|
applyAnnotations(itemStringSchema, itemAnnotations, ctx);
|
|
1127
1127
|
}
|
|
@@ -1164,32 +1164,36 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
1164
1164
|
return schema;
|
|
1165
1165
|
}
|
|
1166
1166
|
if (schema.$ref) {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
properties: propertyOverrides,
|
|
1171
|
-
...rest
|
|
1167
|
+
return {
|
|
1168
|
+
...schema,
|
|
1169
|
+
properties: propertyOverrides
|
|
1172
1170
|
};
|
|
1173
|
-
return { allOf: [refPart, overridePart] };
|
|
1174
1171
|
}
|
|
1175
1172
|
if (schema.type === "object" && schema.properties) {
|
|
1176
|
-
const missingOverrides = {};
|
|
1177
1173
|
for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
|
|
1178
|
-
if (schema.properties
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1174
|
+
if (Object.hasOwn(schema.properties, target)) {
|
|
1175
|
+
const existing = schema.properties[target];
|
|
1176
|
+
if (existing) {
|
|
1177
|
+
mergeSchemaOverride(existing, overrideSchema);
|
|
1178
|
+
continue;
|
|
1179
|
+
}
|
|
1182
1180
|
}
|
|
1181
|
+
Object.defineProperty(schema.properties, target, {
|
|
1182
|
+
value: overrideSchema,
|
|
1183
|
+
writable: true,
|
|
1184
|
+
enumerable: true,
|
|
1185
|
+
configurable: true
|
|
1186
|
+
});
|
|
1183
1187
|
}
|
|
1184
|
-
|
|
1185
|
-
return schema;
|
|
1186
|
-
}
|
|
1187
|
-
return {
|
|
1188
|
-
allOf: [schema, { properties: missingOverrides }]
|
|
1189
|
-
};
|
|
1188
|
+
return schema;
|
|
1190
1189
|
}
|
|
1191
1190
|
if (schema.allOf) {
|
|
1192
|
-
|
|
1191
|
+
const overrideMember = { properties: propertyOverrides };
|
|
1192
|
+
const flattened = tryFlattenAllOfToSiblings(schema, overrideMember);
|
|
1193
|
+
if (flattened !== void 0) {
|
|
1194
|
+
return flattened;
|
|
1195
|
+
}
|
|
1196
|
+
schema.allOf = [...schema.allOf, overrideMember];
|
|
1193
1197
|
return schema;
|
|
1194
1198
|
}
|
|
1195
1199
|
return schema;
|
|
@@ -1302,7 +1306,7 @@ function generatePropertySchema(prop, ctx) {
|
|
|
1302
1306
|
const schema = generateTypeNode(prop.type, ctx);
|
|
1303
1307
|
applyConstraints(schema, prop.constraints, ctx);
|
|
1304
1308
|
applyResolvedMetadata(schema, prop.metadata);
|
|
1305
|
-
applyAnnotations(schema, prop.annotations, ctx);
|
|
1309
|
+
applyAnnotations(schema, prop.annotations, ctx, prop.type);
|
|
1306
1310
|
return schema;
|
|
1307
1311
|
}
|
|
1308
1312
|
function generateUnionType(type, ctx) {
|
|
@@ -1405,13 +1409,20 @@ function buildPropertyOverrides(pathConstraints, typeNode, ctx) {
|
|
|
1405
1409
|
grouped.push(constraint);
|
|
1406
1410
|
byTarget.set(target, grouped);
|
|
1407
1411
|
}
|
|
1408
|
-
const overrides =
|
|
1412
|
+
const overrides = /* @__PURE__ */ Object.create(null);
|
|
1409
1413
|
for (const [target, constraints] of byTarget) {
|
|
1410
|
-
|
|
1414
|
+
const resolvedName = resolveSerializedPropertyName(target, typeNode, ctx);
|
|
1415
|
+
const schema = buildPathOverrideSchema(
|
|
1411
1416
|
constraints.map(stripLeadingPathSegment),
|
|
1412
1417
|
resolveTargetTypeNode(target, typeNode, ctx),
|
|
1413
1418
|
ctx
|
|
1414
1419
|
);
|
|
1420
|
+
Object.defineProperty(overrides, resolvedName, {
|
|
1421
|
+
value: schema,
|
|
1422
|
+
writable: true,
|
|
1423
|
+
enumerable: true,
|
|
1424
|
+
configurable: true
|
|
1425
|
+
});
|
|
1415
1426
|
}
|
|
1416
1427
|
return overrides;
|
|
1417
1428
|
}
|
|
@@ -1438,6 +1449,34 @@ function buildPathOverrideSchema(constraints, typeNode, ctx) {
|
|
|
1438
1449
|
schema.properties = buildPropertyOverrides(nestedConstraints, effectiveType, ctx);
|
|
1439
1450
|
return schema;
|
|
1440
1451
|
}
|
|
1452
|
+
function tryFlattenAllOfToSiblings(schema, overrideMember) {
|
|
1453
|
+
if (schema.allOf?.length !== 1) {
|
|
1454
|
+
return void 0;
|
|
1455
|
+
}
|
|
1456
|
+
const [soleMember] = schema.allOf;
|
|
1457
|
+
if (soleMember === void 0) {
|
|
1458
|
+
return void 0;
|
|
1459
|
+
}
|
|
1460
|
+
const { allOf: _allOf, ...outerRest } = schema;
|
|
1461
|
+
const outerKeys = new Set(Object.keys(outerRest));
|
|
1462
|
+
const memberKeys = new Set(Object.keys(soleMember));
|
|
1463
|
+
const overrideKeys = new Set(Object.keys(overrideMember));
|
|
1464
|
+
for (const key of memberKeys) {
|
|
1465
|
+
if (outerKeys.has(key) || overrideKeys.has(key)) {
|
|
1466
|
+
return void 0;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
for (const key of overrideKeys) {
|
|
1470
|
+
if (outerKeys.has(key)) {
|
|
1471
|
+
return void 0;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
return {
|
|
1475
|
+
...outerRest,
|
|
1476
|
+
...soleMember,
|
|
1477
|
+
...overrideMember
|
|
1478
|
+
};
|
|
1479
|
+
}
|
|
1441
1480
|
function mergeSchemaOverride(target, override) {
|
|
1442
1481
|
const nullableValueBranch = getNullableUnionValueSchema(target);
|
|
1443
1482
|
if (nullableValueBranch !== void 0) {
|
|
@@ -1445,11 +1484,16 @@ function mergeSchemaOverride(target, override) {
|
|
|
1445
1484
|
return;
|
|
1446
1485
|
}
|
|
1447
1486
|
if (override.properties !== void 0) {
|
|
1448
|
-
const mergedProperties = target.properties ??
|
|
1487
|
+
const mergedProperties = target.properties ?? /* @__PURE__ */ Object.create(null);
|
|
1449
1488
|
for (const [name, propertyOverride] of Object.entries(override.properties)) {
|
|
1450
|
-
const existing = mergedProperties[name];
|
|
1489
|
+
const existing = Object.hasOwn(mergedProperties, name) ? mergedProperties[name] : void 0;
|
|
1451
1490
|
if (existing === void 0) {
|
|
1452
|
-
mergedProperties
|
|
1491
|
+
Object.defineProperty(mergedProperties, name, {
|
|
1492
|
+
value: propertyOverride,
|
|
1493
|
+
writable: true,
|
|
1494
|
+
enumerable: true,
|
|
1495
|
+
configurable: true
|
|
1496
|
+
});
|
|
1453
1497
|
} else {
|
|
1454
1498
|
mergeSchemaOverride(existing, propertyOverride);
|
|
1455
1499
|
}
|
|
@@ -1467,7 +1511,12 @@ function mergeSchemaOverride(target, override) {
|
|
|
1467
1511
|
if (key === "properties" || key === "items") {
|
|
1468
1512
|
continue;
|
|
1469
1513
|
}
|
|
1470
|
-
target
|
|
1514
|
+
Object.defineProperty(target, key, {
|
|
1515
|
+
value,
|
|
1516
|
+
writable: true,
|
|
1517
|
+
enumerable: true,
|
|
1518
|
+
configurable: true
|
|
1519
|
+
});
|
|
1471
1520
|
}
|
|
1472
1521
|
}
|
|
1473
1522
|
function stripLeadingPathSegment(constraint) {
|
|
@@ -1567,7 +1616,7 @@ function applyConstraints(schema, constraints, ctx) {
|
|
|
1567
1616
|
}
|
|
1568
1617
|
}
|
|
1569
1618
|
}
|
|
1570
|
-
function applyAnnotations(schema, annotations, ctx) {
|
|
1619
|
+
function applyAnnotations(schema, annotations, ctx, typeNode) {
|
|
1571
1620
|
for (const annotation of annotations) {
|
|
1572
1621
|
switch (annotation.annotationKind) {
|
|
1573
1622
|
case "displayName":
|
|
@@ -1580,7 +1629,7 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
1580
1629
|
schema[`${ctx.vendorPrefix}-remarks`] = annotation.value;
|
|
1581
1630
|
break;
|
|
1582
1631
|
case "defaultValue":
|
|
1583
|
-
schema.default = annotation.value;
|
|
1632
|
+
schema.default = coerceDefaultValue(annotation.value, typeNode, schema, ctx);
|
|
1584
1633
|
break;
|
|
1585
1634
|
case "format":
|
|
1586
1635
|
schema.format = annotation.value;
|
|
@@ -1605,6 +1654,34 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
1605
1654
|
}
|
|
1606
1655
|
}
|
|
1607
1656
|
}
|
|
1657
|
+
function coerceDefaultValue(value, typeNode, emittedSchema, ctx) {
|
|
1658
|
+
if (typeNode?.kind !== "custom") {
|
|
1659
|
+
return value;
|
|
1660
|
+
}
|
|
1661
|
+
const registration = ctx.extensionRegistry?.findType(typeNode.typeId);
|
|
1662
|
+
if (registration === void 0) {
|
|
1663
|
+
return value;
|
|
1664
|
+
}
|
|
1665
|
+
if (registration.serializeDefault !== void 0) {
|
|
1666
|
+
return registration.serializeDefault(value, typeNode.payload);
|
|
1667
|
+
}
|
|
1668
|
+
const declaredType = emittedSchema["type"];
|
|
1669
|
+
if (declaredType === "string" && typeof value !== "string") {
|
|
1670
|
+
if (typeof value === "number") {
|
|
1671
|
+
if (!Number.isFinite(value)) {
|
|
1672
|
+
return value;
|
|
1673
|
+
}
|
|
1674
|
+
return String(value);
|
|
1675
|
+
}
|
|
1676
|
+
if (typeof value === "boolean") {
|
|
1677
|
+
return String(value);
|
|
1678
|
+
}
|
|
1679
|
+
if (typeof value === "bigint") {
|
|
1680
|
+
return value.toString();
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
return value;
|
|
1684
|
+
}
|
|
1608
1685
|
function generateCustomType(type, ctx) {
|
|
1609
1686
|
const registration = ctx.extensionRegistry?.findType(type.typeId);
|
|
1610
1687
|
if (registration === void 0) {
|
|
@@ -2062,7 +2139,9 @@ import {
|
|
|
2062
2139
|
import {
|
|
2063
2140
|
getTagDefinition,
|
|
2064
2141
|
normalizeFormSpecTagName,
|
|
2065
|
-
|
|
2142
|
+
getRegistryLogger,
|
|
2143
|
+
_validateExtensionSetup,
|
|
2144
|
+
logSetupDiagnostics
|
|
2066
2145
|
} from "@formspec/analysis/internal";
|
|
2067
2146
|
function buildConstraintTagSources(extensions) {
|
|
2068
2147
|
return extensions.map((extension) => ({
|
|
@@ -2071,16 +2150,32 @@ function buildConstraintTagSources(extensions) {
|
|
|
2071
2150
|
constraintTags: extension.constraintTags.map((tag) => ({
|
|
2072
2151
|
tagName: normalizeFormSpecTagName(tag.tagName)
|
|
2073
2152
|
}))
|
|
2153
|
+
} : {},
|
|
2154
|
+
// Include customTypes so _validateExtensionSetup can check tsTypeNames for
|
|
2155
|
+
// unsupported built-in overrides and invalid identifier patterns.
|
|
2156
|
+
...extension.types !== void 0 ? {
|
|
2157
|
+
customTypes: extension.types.map((type) => ({
|
|
2158
|
+
// tsTypeNames: deprecated in favour of symbol-based detection, but
|
|
2159
|
+
// still required for name-based validation in _validateExtensionSetup
|
|
2160
|
+
// until the bridge is fully retired (see §synthetic-checker-retirement §4C).
|
|
2161
|
+
tsTypeNames: type.tsTypeNames ?? [type.typeName]
|
|
2162
|
+
}))
|
|
2074
2163
|
} : {}
|
|
2075
2164
|
}));
|
|
2076
2165
|
}
|
|
2077
2166
|
function createExtensionRegistry(extensions) {
|
|
2078
|
-
const registryLog =
|
|
2167
|
+
const registryLog = getRegistryLogger();
|
|
2079
2168
|
registryLog.debug("createExtensionRegistry: constructing", {
|
|
2080
2169
|
extensionCount: extensions.length,
|
|
2081
2170
|
extensionIds: extensions.map((e) => e.extensionId)
|
|
2082
2171
|
});
|
|
2083
|
-
const
|
|
2172
|
+
const extensionTagSources = buildConstraintTagSources(extensions);
|
|
2173
|
+
const setupDiagnostics = _validateExtensionSetup(extensionTagSources);
|
|
2174
|
+
logSetupDiagnostics(registryLog, {
|
|
2175
|
+
diagnosticCount: setupDiagnostics.length,
|
|
2176
|
+
codes: setupDiagnostics.map((d) => d.kind)
|
|
2177
|
+
});
|
|
2178
|
+
const reservedTagSources = extensionTagSources;
|
|
2084
2179
|
let symbolMap = /* @__PURE__ */ new Map();
|
|
2085
2180
|
const typeMap = /* @__PURE__ */ new Map();
|
|
2086
2181
|
const typeNameMap = /* @__PURE__ */ new Map();
|
|
@@ -2217,10 +2312,12 @@ function createExtensionRegistry(extensions) {
|
|
|
2217
2312
|
constraintTagCount: constraintTagMap.size,
|
|
2218
2313
|
broadeningCount: builtinBroadeningMap.size,
|
|
2219
2314
|
annotationCount: annotationMap.size,
|
|
2220
|
-
metadataSlotCount: metadataSlotMap.size
|
|
2315
|
+
metadataSlotCount: metadataSlotMap.size,
|
|
2316
|
+
setupDiagnosticCount: setupDiagnostics.length
|
|
2221
2317
|
});
|
|
2222
2318
|
return {
|
|
2223
2319
|
extensions,
|
|
2320
|
+
setupDiagnostics,
|
|
2224
2321
|
findType: (typeId) => typeMap.get(typeId),
|
|
2225
2322
|
findTypeByName: (typeName) => typeNameMap.get(typeName),
|
|
2226
2323
|
findTypeByBrand: (brand) => brandMap.get(brand),
|
|
@@ -2320,21 +2417,6 @@ var init_schema2 = __esm({
|
|
|
2320
2417
|
|
|
2321
2418
|
// src/extensions/ts-type-utils.ts
|
|
2322
2419
|
import * as ts from "typescript";
|
|
2323
|
-
function collectBrandIdentifiers(type) {
|
|
2324
|
-
if (!type.isIntersection()) {
|
|
2325
|
-
return [];
|
|
2326
|
-
}
|
|
2327
|
-
const brands = [];
|
|
2328
|
-
for (const prop of type.getProperties()) {
|
|
2329
|
-
const decl = prop.valueDeclaration ?? prop.declarations?.[0];
|
|
2330
|
-
if (decl === void 0) continue;
|
|
2331
|
-
if (!ts.isPropertySignature(decl) && !ts.isPropertyDeclaration(decl)) continue;
|
|
2332
|
-
if (!ts.isComputedPropertyName(decl.name)) continue;
|
|
2333
|
-
if (!ts.isIdentifier(decl.name.expression)) continue;
|
|
2334
|
-
brands.push(decl.name.expression.text);
|
|
2335
|
-
}
|
|
2336
|
-
return brands;
|
|
2337
|
-
}
|
|
2338
2420
|
function resolveCanonicalSymbol(type, checker) {
|
|
2339
2421
|
const raw = type.aliasSymbol ?? type.getSymbol();
|
|
2340
2422
|
if (raw === void 0) return void 0;
|
|
@@ -2365,7 +2447,7 @@ var init_ts_type_utils = __esm({
|
|
|
2365
2447
|
|
|
2366
2448
|
// src/extensions/resolve-custom-type.ts
|
|
2367
2449
|
import * as ts2 from "typescript";
|
|
2368
|
-
import { stripNullishUnion } from "@formspec/analysis/internal";
|
|
2450
|
+
import { _collectBrandIdentifiers, stripNullishUnion } from "@formspec/analysis/internal";
|
|
2369
2451
|
function getTypeNodeRegistrationName(typeNode) {
|
|
2370
2452
|
if (ts2.isTypeReferenceNode(typeNode)) {
|
|
2371
2453
|
return ts2.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : typeNode.typeName.right.text;
|
|
@@ -2426,7 +2508,7 @@ function resolveCustomTypeFromTsType(type, checker, registry, sourceNode) {
|
|
|
2426
2508
|
return bySymbol;
|
|
2427
2509
|
}
|
|
2428
2510
|
}
|
|
2429
|
-
for (const brand of
|
|
2511
|
+
for (const brand of _collectBrandIdentifiers(stripped)) {
|
|
2430
2512
|
const byBrand = registry.findTypeByBrand(brand);
|
|
2431
2513
|
if (byBrand !== void 0) {
|
|
2432
2514
|
return byBrand;
|
|
@@ -2445,25 +2527,21 @@ var init_resolve_custom_type = __esm({
|
|
|
2445
2527
|
});
|
|
2446
2528
|
|
|
2447
2529
|
// src/analyzer/builtin-brands.ts
|
|
2448
|
-
import
|
|
2449
|
-
function isIntegerBrandedType(type) {
|
|
2450
|
-
if (!type.isIntersection()) return false;
|
|
2451
|
-
if (!type.types.some((member) => !!(member.flags & ts3.TypeFlags.Number))) return false;
|
|
2452
|
-
return collectBrandIdentifiers(type).includes("__integerBrand");
|
|
2453
|
-
}
|
|
2530
|
+
import { _isIntegerBrandedType } from "@formspec/analysis/internal";
|
|
2454
2531
|
var init_builtin_brands = __esm({
|
|
2455
2532
|
"src/analyzer/builtin-brands.ts"() {
|
|
2456
2533
|
"use strict";
|
|
2457
|
-
init_ts_type_utils();
|
|
2458
2534
|
}
|
|
2459
2535
|
});
|
|
2460
2536
|
|
|
2461
2537
|
// src/analyzer/tsdoc-parser.ts
|
|
2462
|
-
import * as
|
|
2538
|
+
import * as ts3 from "typescript";
|
|
2463
2539
|
import {
|
|
2464
|
-
|
|
2540
|
+
_capabilityLabel,
|
|
2541
|
+
_supportsConstraintCapability,
|
|
2465
2542
|
choosePreferredPayloadText,
|
|
2466
2543
|
extractPathTarget as extractSharedPathTarget,
|
|
2544
|
+
getBroadenedCustomTypeId,
|
|
2467
2545
|
getTagDefinition as getTagDefinition2,
|
|
2468
2546
|
hasTypeSemanticCapability,
|
|
2469
2547
|
normalizeFormSpecTagName as normalizeFormSpecTagName2,
|
|
@@ -2484,161 +2562,46 @@ import {
|
|
|
2484
2562
|
import "@formspec/core/internals";
|
|
2485
2563
|
import { noopLogger as noopLogger4 } from "@formspec/core";
|
|
2486
2564
|
import {
|
|
2565
|
+
_emitSetupDiagnostics,
|
|
2487
2566
|
getBuildLogger,
|
|
2488
2567
|
getBroadeningLogger,
|
|
2489
|
-
getSyntheticLogger as getSyntheticLogger2,
|
|
2490
2568
|
getTypedParserLogger,
|
|
2569
|
+
extractEffectiveArgumentText,
|
|
2570
|
+
mapTypedParserDiagnosticCode,
|
|
2491
2571
|
parseTagArgument,
|
|
2492
2572
|
describeTypeKind,
|
|
2493
2573
|
elapsedMicros,
|
|
2494
2574
|
nowMicros,
|
|
2495
2575
|
logTagApplication
|
|
2496
2576
|
} from "@formspec/analysis/internal";
|
|
2497
|
-
function sharedTagValueOptions(options) {
|
|
2577
|
+
function sharedTagValueOptions(options, pathResolvedCustomTypeId) {
|
|
2498
2578
|
return {
|
|
2499
2579
|
...options?.extensionRegistry !== void 0 ? { registry: options.extensionRegistry } : {},
|
|
2500
|
-
...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {}
|
|
2580
|
+
...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {},
|
|
2581
|
+
...pathResolvedCustomTypeId !== void 0 ? { pathResolvedCustomTypeId } : {}
|
|
2501
2582
|
};
|
|
2502
2583
|
}
|
|
2503
|
-
function
|
|
2504
|
-
if (registry === void 0)
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
return new Set(
|
|
2508
|
-
registry.extensions.flatMap(
|
|
2509
|
-
(ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
|
|
2510
|
-
)
|
|
2511
|
-
);
|
|
2512
|
-
}
|
|
2513
|
-
function collectImportedNames(sourceFile) {
|
|
2514
|
-
const importedNames = /* @__PURE__ */ new Set();
|
|
2515
|
-
for (const statement of sourceFile.statements) {
|
|
2516
|
-
if (ts4.isImportDeclaration(statement) && statement.importClause !== void 0) {
|
|
2517
|
-
const clause = statement.importClause;
|
|
2518
|
-
if (clause.name !== void 0) {
|
|
2519
|
-
importedNames.add(clause.name.text);
|
|
2520
|
-
}
|
|
2521
|
-
if (clause.namedBindings !== void 0) {
|
|
2522
|
-
if (ts4.isNamedImports(clause.namedBindings)) {
|
|
2523
|
-
for (const specifier of clause.namedBindings.elements) {
|
|
2524
|
-
importedNames.add(specifier.name.text);
|
|
2525
|
-
}
|
|
2526
|
-
} else if (ts4.isNamespaceImport(clause.namedBindings)) {
|
|
2527
|
-
importedNames.add(clause.namedBindings.name.text);
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2530
|
-
continue;
|
|
2531
|
-
}
|
|
2532
|
-
if (ts4.isImportEqualsDeclaration(statement)) {
|
|
2533
|
-
importedNames.add(statement.name.text);
|
|
2534
|
-
}
|
|
2535
|
-
}
|
|
2536
|
-
return importedNames;
|
|
2584
|
+
function customTypeIdForResolvedType(resolvedType, checker, registry) {
|
|
2585
|
+
if (registry === void 0) return void 0;
|
|
2586
|
+
const lookup = resolveCustomTypeFromTsType(resolvedType, checker, registry);
|
|
2587
|
+
return lookup === null ? void 0 : customTypeIdFromLookup(lookup);
|
|
2537
2588
|
}
|
|
2538
|
-
function
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
if ((ts4.isPropertyAssignment(parent) || ts4.isPropertyAccessExpression(parent)) && parent.name === node) {
|
|
2544
|
-
return true;
|
|
2545
|
-
}
|
|
2546
|
-
if (ts4.isQualifiedName(parent) && parent.right === node) {
|
|
2547
|
-
return true;
|
|
2548
|
-
}
|
|
2549
|
-
return false;
|
|
2550
|
-
}
|
|
2551
|
-
function astReferencesImportedName(root, importedNames) {
|
|
2552
|
-
if (importedNames.size === 0) {
|
|
2553
|
-
return false;
|
|
2554
|
-
}
|
|
2555
|
-
let found = false;
|
|
2556
|
-
const visit = (node) => {
|
|
2557
|
-
if (found) return;
|
|
2558
|
-
if (ts4.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
|
|
2559
|
-
found = true;
|
|
2560
|
-
return;
|
|
2561
|
-
}
|
|
2562
|
-
ts4.forEachChild(node, visit);
|
|
2563
|
-
};
|
|
2564
|
-
visit(root);
|
|
2565
|
-
return found;
|
|
2566
|
-
}
|
|
2567
|
-
function getObjectMembers(statement) {
|
|
2568
|
-
if (ts4.isInterfaceDeclaration(statement)) {
|
|
2569
|
-
return statement.members;
|
|
2570
|
-
}
|
|
2571
|
-
if (ts4.isTypeLiteralNode(statement.type)) {
|
|
2572
|
-
return statement.type.members;
|
|
2573
|
-
}
|
|
2574
|
-
return void 0;
|
|
2575
|
-
}
|
|
2576
|
-
function rewriteImportedMemberTypes(statement, sourceFile, importedNames) {
|
|
2577
|
-
const members = getObjectMembers(statement);
|
|
2578
|
-
if (members === void 0) {
|
|
2579
|
-
return null;
|
|
2580
|
-
}
|
|
2581
|
-
const replacements = [];
|
|
2582
|
-
for (const member of members) {
|
|
2583
|
-
if (!ts4.isPropertySignature(member)) {
|
|
2584
|
-
if (astReferencesImportedName(member, importedNames)) {
|
|
2585
|
-
return null;
|
|
2586
|
-
}
|
|
2587
|
-
continue;
|
|
2588
|
-
}
|
|
2589
|
-
const typeAnnotation = member.type;
|
|
2590
|
-
if (typeAnnotation === void 0) continue;
|
|
2591
|
-
if (astReferencesImportedName(typeAnnotation, importedNames)) {
|
|
2592
|
-
replacements.push({
|
|
2593
|
-
start: typeAnnotation.getStart(sourceFile),
|
|
2594
|
-
end: typeAnnotation.getEnd()
|
|
2595
|
-
});
|
|
2596
|
-
}
|
|
2597
|
-
}
|
|
2598
|
-
if (replacements.length === 0) {
|
|
2599
|
-
return statement.getText(sourceFile);
|
|
2600
|
-
}
|
|
2601
|
-
const stmtStart = statement.getStart(sourceFile);
|
|
2602
|
-
let result = statement.getText(sourceFile);
|
|
2603
|
-
for (const { start, end } of [...replacements].reverse()) {
|
|
2604
|
-
result = result.slice(0, start - stmtStart) + "unknown" + result.slice(end - stmtStart);
|
|
2589
|
+
function resolvePathTargetCustomTypeId(parsedTag, subjectType, checker, registry) {
|
|
2590
|
+
if (parsedTag === null) return void 0;
|
|
2591
|
+
const target = parsedTag.target;
|
|
2592
|
+
if (target?.kind !== "path" || !target.valid || target.path === null) {
|
|
2593
|
+
return void 0;
|
|
2605
2594
|
}
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
|
|
2609
|
-
const importedNames = collectImportedNames(sourceFile);
|
|
2610
|
-
const importedNamesToSkip = new Set(
|
|
2611
|
-
[...importedNames].filter((name) => !extensionTypeNames.has(name))
|
|
2612
|
-
);
|
|
2613
|
-
const result = [];
|
|
2614
|
-
for (const statement of sourceFile.statements) {
|
|
2615
|
-
if (ts4.isImportDeclaration(statement)) continue;
|
|
2616
|
-
if (ts4.isImportEqualsDeclaration(statement)) continue;
|
|
2617
|
-
if (ts4.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0) continue;
|
|
2618
|
-
if (!astReferencesImportedName(statement, importedNamesToSkip)) {
|
|
2619
|
-
result.push(statement.getText(sourceFile));
|
|
2620
|
-
continue;
|
|
2621
|
-
}
|
|
2622
|
-
if (ts4.isInterfaceDeclaration(statement) || ts4.isTypeAliasDeclaration(statement)) {
|
|
2623
|
-
const rewritten = rewriteImportedMemberTypes(statement, sourceFile, importedNamesToSkip);
|
|
2624
|
-
if (rewritten !== null) {
|
|
2625
|
-
result.push(rewritten);
|
|
2626
|
-
}
|
|
2627
|
-
}
|
|
2595
|
+
if (subjectType === void 0 || checker === void 0) {
|
|
2596
|
+
return void 0;
|
|
2628
2597
|
}
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
for (const diagnostic of additions) {
|
|
2633
|
-
if ((diagnostic.code === "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" || diagnostic.code === "SYNTHETIC_SETUP_FAILURE") && target.some(
|
|
2634
|
-
(existing) => existing.code === diagnostic.code && existing.message === diagnostic.message
|
|
2635
|
-
)) {
|
|
2636
|
-
continue;
|
|
2637
|
-
}
|
|
2638
|
-
target.push(diagnostic);
|
|
2598
|
+
const resolution = resolvePathTargetType(subjectType, checker, target.path.segments);
|
|
2599
|
+
if (resolution.kind !== "resolved") {
|
|
2600
|
+
return void 0;
|
|
2639
2601
|
}
|
|
2602
|
+
return customTypeIdForResolvedType(resolution.type, checker, registry);
|
|
2640
2603
|
}
|
|
2641
|
-
function processConstraintTag(tagName, text, parsedTag, provenance, node, sourceFile,
|
|
2604
|
+
function processConstraintTag(tagName, text, parsedTag, provenance, node, sourceFile, options, constraints, diagnostics) {
|
|
2642
2605
|
const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
|
|
2643
2606
|
node,
|
|
2644
2607
|
sourceFile,
|
|
@@ -2646,81 +2609,37 @@ function processConstraintTag(tagName, text, parsedTag, provenance, node, source
|
|
|
2646
2609
|
parsedTag,
|
|
2647
2610
|
text,
|
|
2648
2611
|
provenance,
|
|
2649
|
-
supportingDeclarations,
|
|
2650
2612
|
options
|
|
2651
2613
|
);
|
|
2652
2614
|
if (compilerDiagnostics.length > 0) {
|
|
2653
|
-
|
|
2615
|
+
diagnostics.push(...compilerDiagnostics);
|
|
2654
2616
|
return;
|
|
2655
2617
|
}
|
|
2618
|
+
const pathResolvedCustomTypeId = resolvePathTargetCustomTypeId(
|
|
2619
|
+
parsedTag,
|
|
2620
|
+
options?.subjectType,
|
|
2621
|
+
options?.checker,
|
|
2622
|
+
options?.extensionRegistry
|
|
2623
|
+
);
|
|
2656
2624
|
const constraintNode = parseConstraintTagValue(
|
|
2657
2625
|
tagName,
|
|
2658
2626
|
text,
|
|
2659
2627
|
provenance,
|
|
2660
|
-
sharedTagValueOptions(options)
|
|
2628
|
+
sharedTagValueOptions(options, pathResolvedCustomTypeId)
|
|
2661
2629
|
);
|
|
2662
2630
|
if (constraintNode) {
|
|
2663
2631
|
constraints.push(constraintNode);
|
|
2664
2632
|
}
|
|
2665
2633
|
}
|
|
2666
|
-
function renderSyntheticArgumentExpression(valueKind, argumentText) {
|
|
2667
|
-
const trimmed = argumentText.trim();
|
|
2668
|
-
if (trimmed === "") {
|
|
2669
|
-
return null;
|
|
2670
|
-
}
|
|
2671
|
-
switch (valueKind) {
|
|
2672
|
-
case "number":
|
|
2673
|
-
case "integer":
|
|
2674
|
-
case "signedInteger":
|
|
2675
|
-
if (trimmed === "Infinity" || trimmed === "-Infinity" || trimmed === "NaN") {
|
|
2676
|
-
return trimmed;
|
|
2677
|
-
}
|
|
2678
|
-
return Number.isFinite(Number(trimmed)) ? trimmed : JSON.stringify(trimmed);
|
|
2679
|
-
case "string":
|
|
2680
|
-
return JSON.stringify(argumentText);
|
|
2681
|
-
case "json":
|
|
2682
|
-
try {
|
|
2683
|
-
JSON.parse(trimmed);
|
|
2684
|
-
return `(${trimmed})`;
|
|
2685
|
-
} catch {
|
|
2686
|
-
return JSON.stringify(trimmed);
|
|
2687
|
-
}
|
|
2688
|
-
case "boolean":
|
|
2689
|
-
return trimmed === "true" || trimmed === "false" ? trimmed : JSON.stringify(trimmed);
|
|
2690
|
-
case "condition":
|
|
2691
|
-
return "undefined as unknown as FormSpecCondition";
|
|
2692
|
-
case null:
|
|
2693
|
-
return null;
|
|
2694
|
-
default: {
|
|
2695
|
-
return String(valueKind);
|
|
2696
|
-
}
|
|
2697
|
-
}
|
|
2698
|
-
}
|
|
2699
|
-
function getArrayElementType(type, checker) {
|
|
2700
|
-
if (!checker.isArrayType(type)) {
|
|
2701
|
-
return null;
|
|
2702
|
-
}
|
|
2703
|
-
return checker.getTypeArguments(type)[0] ?? null;
|
|
2704
|
-
}
|
|
2705
2634
|
function supportsConstraintCapability(type, checker, capability) {
|
|
2706
|
-
|
|
2707
|
-
return true;
|
|
2708
|
-
}
|
|
2709
|
-
if (hasTypeSemanticCapability(type, checker, capability)) {
|
|
2710
|
-
return true;
|
|
2711
|
-
}
|
|
2712
|
-
if (capability === "string-like") {
|
|
2713
|
-
const itemType = getArrayElementType(type, checker);
|
|
2714
|
-
return itemType !== null && hasTypeSemanticCapability(itemType, checker, capability);
|
|
2715
|
-
}
|
|
2716
|
-
return false;
|
|
2635
|
+
return _supportsConstraintCapability(capability, type, checker);
|
|
2717
2636
|
}
|
|
2718
2637
|
function stripHintNullishUnion(type) {
|
|
2719
2638
|
if (!type.isUnion()) {
|
|
2720
2639
|
return type;
|
|
2721
2640
|
}
|
|
2722
2641
|
const nonNullish = type.types.filter(
|
|
2723
|
-
(member) => (member.flags & (
|
|
2642
|
+
(member) => (member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined)) === 0
|
|
2724
2643
|
);
|
|
2725
2644
|
if (nonNullish.length === 1 && nonNullish[0] !== void 0) {
|
|
2726
2645
|
return nonNullish[0];
|
|
@@ -2736,10 +2655,10 @@ function isUserEmittableHintProperty(property, declaration) {
|
|
|
2736
2655
|
}
|
|
2737
2656
|
if ("name" in declaration && declaration.name !== void 0) {
|
|
2738
2657
|
const name = declaration.name;
|
|
2739
|
-
if (
|
|
2658
|
+
if (ts3.isComputedPropertyName(name) || ts3.isPrivateIdentifier(name)) {
|
|
2740
2659
|
return false;
|
|
2741
2660
|
}
|
|
2742
|
-
if (!
|
|
2661
|
+
if (!ts3.isIdentifier(name) && !ts3.isStringLiteral(name) && !ts3.isNumericLiteral(name)) {
|
|
2743
2662
|
return false;
|
|
2744
2663
|
}
|
|
2745
2664
|
}
|
|
@@ -2838,53 +2757,11 @@ function placementLabel(placement) {
|
|
|
2838
2757
|
}
|
|
2839
2758
|
}
|
|
2840
2759
|
}
|
|
2841
|
-
function capabilityLabel(capability) {
|
|
2842
|
-
switch (capability) {
|
|
2843
|
-
case "numeric-comparable":
|
|
2844
|
-
return "number";
|
|
2845
|
-
case "string-like":
|
|
2846
|
-
return "string";
|
|
2847
|
-
case "array-like":
|
|
2848
|
-
return "array";
|
|
2849
|
-
case "enum-member-addressable":
|
|
2850
|
-
return "enum";
|
|
2851
|
-
case "json-like":
|
|
2852
|
-
return "JSON-compatible";
|
|
2853
|
-
case "object-like":
|
|
2854
|
-
return "object";
|
|
2855
|
-
case "condition-like":
|
|
2856
|
-
return "conditional";
|
|
2857
|
-
case void 0:
|
|
2858
|
-
return "compatible";
|
|
2859
|
-
default:
|
|
2860
|
-
return capability;
|
|
2861
|
-
}
|
|
2862
|
-
}
|
|
2863
|
-
function getBroadenedCustomTypeId(fieldType) {
|
|
2864
|
-
if (fieldType?.kind === "custom") {
|
|
2865
|
-
return fieldType.typeId;
|
|
2866
|
-
}
|
|
2867
|
-
if (fieldType?.kind !== "union") {
|
|
2868
|
-
return void 0;
|
|
2869
|
-
}
|
|
2870
|
-
const customMembers = fieldType.members.filter(
|
|
2871
|
-
(member) => member.kind === "custom"
|
|
2872
|
-
);
|
|
2873
|
-
if (customMembers.length !== 1) {
|
|
2874
|
-
return void 0;
|
|
2875
|
-
}
|
|
2876
|
-
const nonCustomMembers = fieldType.members.filter((member) => member.kind !== "custom");
|
|
2877
|
-
const allOtherMembersAreNull = nonCustomMembers.every(
|
|
2878
|
-
(member) => member.kind === "primitive" && member.primitiveKind === "null"
|
|
2879
|
-
);
|
|
2880
|
-
const customMember = customMembers[0];
|
|
2881
|
-
return allOtherMembersAreNull && customMember !== void 0 ? customMember.typeId : void 0;
|
|
2882
|
-
}
|
|
2883
2760
|
function hasBuiltinConstraintBroadening(tagName, options) {
|
|
2884
2761
|
const broadenedTypeId = getBroadenedCustomTypeId(options?.fieldType);
|
|
2885
2762
|
return broadenedTypeId !== void 0 && options?.extensionRegistry?.findBuiltinConstraintBroadening(broadenedTypeId, tagName) !== void 0;
|
|
2886
2763
|
}
|
|
2887
|
-
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance,
|
|
2764
|
+
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance, options) {
|
|
2888
2765
|
if (!isBuiltinConstraintName(tagName)) {
|
|
2889
2766
|
return [];
|
|
2890
2767
|
}
|
|
@@ -2904,16 +2781,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2904
2781
|
const nonNullPlacement = placement;
|
|
2905
2782
|
const log2 = getBuildLogger();
|
|
2906
2783
|
const broadeningLog = getBroadeningLogger();
|
|
2907
|
-
const syntheticLog = getSyntheticLogger2();
|
|
2908
2784
|
const typedParserLog = getTypedParserLogger();
|
|
2909
2785
|
const logsEnabled = log2 !== noopLogger4 || broadeningLog !== noopLogger4;
|
|
2910
|
-
const syntheticTraceEnabled = syntheticLog !== noopLogger4;
|
|
2911
2786
|
const typedParserTraceEnabled = typedParserLog !== noopLogger4;
|
|
2912
2787
|
const logStart = logsEnabled ? nowMicros() : 0;
|
|
2913
2788
|
const subjectTypeKind = logsEnabled ? describeTypeKind(subjectType, checker) : "";
|
|
2914
|
-
function emit(outcome,
|
|
2789
|
+
function emit(outcome, result) {
|
|
2915
2790
|
if (!logsEnabled) {
|
|
2916
|
-
return
|
|
2791
|
+
return result;
|
|
2917
2792
|
}
|
|
2918
2793
|
const entry = {
|
|
2919
2794
|
consumer: "build",
|
|
@@ -2927,7 +2802,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2927
2802
|
if (outcome === "bypass" || outcome === "D1" || outcome === "D2") {
|
|
2928
2803
|
logTagApplication(broadeningLog, entry);
|
|
2929
2804
|
}
|
|
2930
|
-
return
|
|
2805
|
+
return result;
|
|
2931
2806
|
}
|
|
2932
2807
|
if (!definition.placements.includes(placement)) {
|
|
2933
2808
|
return emit("A-reject", [
|
|
@@ -2971,7 +2846,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2971
2846
|
]);
|
|
2972
2847
|
}
|
|
2973
2848
|
if (resolution.kind === "unresolvable") {
|
|
2974
|
-
const actualType = checker.typeToString(resolution.type, node,
|
|
2849
|
+
const actualType = checker.typeToString(resolution.type, node, TYPE_FORMAT_FLAGS);
|
|
2975
2850
|
return emit("B-reject", [
|
|
2976
2851
|
makeDiagnostic(
|
|
2977
2852
|
"TYPE_MISMATCH",
|
|
@@ -2985,21 +2860,21 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2985
2860
|
}
|
|
2986
2861
|
const hasBroadening = (() => {
|
|
2987
2862
|
if (target === null) {
|
|
2988
|
-
if (
|
|
2863
|
+
if (_isIntegerBrandedType(stripNullishUnion2(subjectType)) && definition.capabilities[0] === "numeric-comparable") {
|
|
2989
2864
|
return true;
|
|
2990
2865
|
}
|
|
2991
2866
|
return hasBuiltinConstraintBroadening(tagName, options);
|
|
2992
2867
|
}
|
|
2993
2868
|
const registry = options?.extensionRegistry;
|
|
2994
2869
|
if (registry === void 0) return false;
|
|
2995
|
-
const
|
|
2996
|
-
return
|
|
2870
|
+
const typeId = customTypeIdForResolvedType(evaluatedType, checker, registry);
|
|
2871
|
+
return typeId !== void 0 && registry.findBuiltinConstraintBroadening(typeId, tagName) !== void 0;
|
|
2997
2872
|
})();
|
|
2998
2873
|
if (!hasBroadening) {
|
|
2999
2874
|
const requiredCapability = definition.capabilities[0];
|
|
3000
2875
|
if (requiredCapability !== void 0 && !supportsConstraintCapability(evaluatedType, checker, requiredCapability)) {
|
|
3001
|
-
const actualType = checker.typeToString(evaluatedType, node,
|
|
3002
|
-
const baseMessage = `Target "${targetLabel}": constraint "${tagName}" is only valid on ${
|
|
2876
|
+
const actualType = checker.typeToString(evaluatedType, node, TYPE_FORMAT_FLAGS);
|
|
2877
|
+
const baseMessage = `Target "${targetLabel}": constraint "${tagName}" is only valid on ${_capabilityLabel(requiredCapability)} targets, but field type is "${actualType}"`;
|
|
3003
2878
|
const hint = target === null ? buildPathTargetHint(
|
|
3004
2879
|
subjectType,
|
|
3005
2880
|
checker,
|
|
@@ -3016,10 +2891,10 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
3016
2891
|
]);
|
|
3017
2892
|
}
|
|
3018
2893
|
}
|
|
3019
|
-
const effectiveArgumentText = parsedTag !== null ? parseTagSyntax(tagName, rawText).argumentText : rawText;
|
|
3020
2894
|
if (hasBroadening) {
|
|
3021
2895
|
return emit("bypass", []);
|
|
3022
2896
|
}
|
|
2897
|
+
const effectiveArgumentText = extractEffectiveArgumentText(tagName, rawText, parsedTag);
|
|
3023
2898
|
const typedParseResult = parseTagArgument(tagName, effectiveArgumentText, "build");
|
|
3024
2899
|
if (!typedParseResult.ok) {
|
|
3025
2900
|
if (typedParserTraceEnabled) {
|
|
@@ -3032,23 +2907,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
3032
2907
|
diagnosticCode: typedParseResult.diagnostic.code
|
|
3033
2908
|
});
|
|
3034
2909
|
}
|
|
3035
|
-
|
|
3036
|
-
switch (typedParseResult.diagnostic.code) {
|
|
3037
|
-
case "MISSING_TAG_ARGUMENT":
|
|
3038
|
-
mappedCode = "MISSING_TAG_ARGUMENT";
|
|
3039
|
-
break;
|
|
3040
|
-
case "INVALID_TAG_ARGUMENT":
|
|
3041
|
-
mappedCode = "INVALID_TAG_ARGUMENT";
|
|
3042
|
-
break;
|
|
3043
|
-
case "UNKNOWN_TAG":
|
|
3044
|
-
throw new Error(
|
|
3045
|
-
`Unexpected UNKNOWN_TAG from parseTagArgument("${tagName}") \u2014 tag was resolved via getTagDefinition.`
|
|
3046
|
-
);
|
|
3047
|
-
default: {
|
|
3048
|
-
const _exhaustive = typedParseResult.diagnostic.code;
|
|
3049
|
-
throw new Error(`Unknown diagnostic code: ${String(_exhaustive)}`);
|
|
3050
|
-
}
|
|
3051
|
-
}
|
|
2910
|
+
const mappedCode = mapTypedParserDiagnosticCode(typedParseResult.diagnostic.code, tagName);
|
|
3052
2911
|
return emit("C-reject", [
|
|
3053
2912
|
makeDiagnostic(mappedCode, typedParseResult.diagnostic.message, provenance)
|
|
3054
2913
|
]);
|
|
@@ -3063,68 +2922,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
3063
2922
|
valueKind: typedParseResult.value.kind
|
|
3064
2923
|
});
|
|
3065
2924
|
}
|
|
3066
|
-
|
|
3067
|
-
definition.valueKind,
|
|
3068
|
-
effectiveArgumentText
|
|
3069
|
-
);
|
|
3070
|
-
const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
3071
|
-
const hostType = options?.hostType ?? subjectType;
|
|
3072
|
-
const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
3073
|
-
if (syntheticTraceEnabled) {
|
|
3074
|
-
syntheticLog.trace("invoking synthetic checker", {
|
|
3075
|
-
consumer: "build",
|
|
3076
|
-
tag: tagName,
|
|
3077
|
-
placement,
|
|
3078
|
-
subjectTypeKind,
|
|
3079
|
-
subjectTypeText
|
|
3080
|
-
});
|
|
3081
|
-
}
|
|
3082
|
-
const result = checkSyntheticTagApplication({
|
|
3083
|
-
tagName,
|
|
3084
|
-
placement,
|
|
3085
|
-
hostType: hostTypeText,
|
|
3086
|
-
subjectType: subjectTypeText,
|
|
3087
|
-
...target?.kind === "path" ? { target: { kind: "path", text: target.rawText } } : {},
|
|
3088
|
-
...argumentExpression !== null ? { argumentExpression } : {},
|
|
3089
|
-
supportingDeclarations,
|
|
3090
|
-
...options?.extensionRegistry !== void 0 ? {
|
|
3091
|
-
extensions: options.extensionRegistry.extensions.map((extension) => ({
|
|
3092
|
-
extensionId: extension.extensionId,
|
|
3093
|
-
...extension.constraintTags !== void 0 ? {
|
|
3094
|
-
constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
|
|
3095
|
-
} : {},
|
|
3096
|
-
...extension.metadataSlots !== void 0 ? {
|
|
3097
|
-
metadataSlots: extension.metadataSlots
|
|
3098
|
-
} : {},
|
|
3099
|
-
...extension.types !== void 0 ? {
|
|
3100
|
-
customTypes: extension.types.map((t) => ({
|
|
3101
|
-
tsTypeNames: t.tsTypeNames ?? [t.typeName]
|
|
3102
|
-
}))
|
|
3103
|
-
} : {}
|
|
3104
|
-
}))
|
|
3105
|
-
} : {}
|
|
3106
|
-
});
|
|
3107
|
-
if (result.diagnostics.length === 0) {
|
|
3108
|
-
return emit("C-pass", []);
|
|
3109
|
-
}
|
|
3110
|
-
const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
|
|
3111
|
-
if (setupDiagnostic !== void 0) {
|
|
3112
|
-
return emit("C-reject", [
|
|
3113
|
-
makeDiagnostic(
|
|
3114
|
-
setupDiagnostic.kind === "unsupported-custom-type-override" ? "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" : "SYNTHETIC_SETUP_FAILURE",
|
|
3115
|
-
setupDiagnostic.message,
|
|
3116
|
-
provenance
|
|
3117
|
-
)
|
|
3118
|
-
]);
|
|
3119
|
-
}
|
|
3120
|
-
const expectedLabel = definition.valueKind === null ? "compatible argument" : capabilityLabel(definition.valueKind);
|
|
3121
|
-
return emit("C-reject", [
|
|
3122
|
-
makeDiagnostic(
|
|
3123
|
-
"TYPE_MISMATCH",
|
|
3124
|
-
`Tag "@${tagName}" received an invalid argument for ${expectedLabel}.`,
|
|
3125
|
-
provenance
|
|
3126
|
-
)
|
|
3127
|
-
]);
|
|
2925
|
+
return emit("C-pass", []);
|
|
3128
2926
|
}
|
|
3129
2927
|
function getExtensionTagNames(options) {
|
|
3130
2928
|
return [
|
|
@@ -3167,8 +2965,8 @@ function getParseCacheKey(node, file, options) {
|
|
|
3167
2965
|
start: node.getFullStart(),
|
|
3168
2966
|
end: node.getEnd(),
|
|
3169
2967
|
fieldType: options?.fieldType ?? null,
|
|
3170
|
-
subjectType: checker !== void 0 && options?.subjectType !== void 0 ? checker.typeToString(options.subjectType, node,
|
|
3171
|
-
hostType: checker !== void 0 && options?.hostType !== void 0 ? checker.typeToString(options.hostType, node,
|
|
2968
|
+
subjectType: checker !== void 0 && options?.subjectType !== void 0 ? checker.typeToString(options.subjectType, node, TYPE_FORMAT_FLAGS) : null,
|
|
2969
|
+
hostType: checker !== void 0 && options?.hostType !== void 0 ? checker.typeToString(options.hostType, node, TYPE_FORMAT_FLAGS) : null,
|
|
3172
2970
|
extensions: getExtensionRegistryCacheKey(options?.extensionRegistry)
|
|
3173
2971
|
});
|
|
3174
2972
|
}
|
|
@@ -3178,6 +2976,16 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3178
2976
|
if (cached !== void 0) {
|
|
3179
2977
|
return cached;
|
|
3180
2978
|
}
|
|
2979
|
+
const setupDiags = options?.extensionRegistry?.setupDiagnostics;
|
|
2980
|
+
if (setupDiags !== void 0 && setupDiags.length > 0) {
|
|
2981
|
+
const result2 = {
|
|
2982
|
+
constraints: [],
|
|
2983
|
+
annotations: [],
|
|
2984
|
+
diagnostics: _emitSetupDiagnostics(setupDiags, file)
|
|
2985
|
+
};
|
|
2986
|
+
parseResultCache.set(cacheKey, result2);
|
|
2987
|
+
return result2;
|
|
2988
|
+
}
|
|
3181
2989
|
const constraints = [];
|
|
3182
2990
|
const annotations = [];
|
|
3183
2991
|
const diagnostics = [];
|
|
@@ -3187,14 +2995,12 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3187
2995
|
let placeholderProvenance;
|
|
3188
2996
|
const sourceFile = node.getSourceFile();
|
|
3189
2997
|
const sourceText = sourceFile.getFullText();
|
|
3190
|
-
const
|
|
3191
|
-
const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
|
|
3192
|
-
const commentRanges = ts4.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
2998
|
+
const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
3193
2999
|
const rawTextFallbacks = collectRawTextFallbacks(node, file);
|
|
3194
3000
|
const extensionTagNames = getExtensionTagNames(options);
|
|
3195
3001
|
if (commentRanges) {
|
|
3196
3002
|
for (const range of commentRanges) {
|
|
3197
|
-
if (range.kind !==
|
|
3003
|
+
if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) {
|
|
3198
3004
|
continue;
|
|
3199
3005
|
}
|
|
3200
3006
|
const commentText = sourceText.substring(range.pos, range.end);
|
|
@@ -3253,7 +3059,6 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3253
3059
|
provenance2,
|
|
3254
3060
|
node,
|
|
3255
3061
|
sourceFile,
|
|
3256
|
-
supportingDeclarations,
|
|
3257
3062
|
options,
|
|
3258
3063
|
constraints,
|
|
3259
3064
|
diagnostics
|
|
@@ -3271,7 +3076,6 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3271
3076
|
provenance,
|
|
3272
3077
|
node,
|
|
3273
3078
|
sourceFile,
|
|
3274
|
-
supportingDeclarations,
|
|
3275
3079
|
options,
|
|
3276
3080
|
constraints,
|
|
3277
3081
|
diagnostics
|
|
@@ -3335,7 +3139,6 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
3335
3139
|
provenance,
|
|
3336
3140
|
node,
|
|
3337
3141
|
sourceFile,
|
|
3338
|
-
supportingDeclarations,
|
|
3339
3142
|
options,
|
|
3340
3143
|
constraints,
|
|
3341
3144
|
diagnostics
|
|
@@ -3351,10 +3154,10 @@ function extractDisplayNameMetadata(node) {
|
|
|
3351
3154
|
const memberDisplayNames = /* @__PURE__ */ new Map();
|
|
3352
3155
|
const sourceFile = node.getSourceFile();
|
|
3353
3156
|
const sourceText = sourceFile.getFullText();
|
|
3354
|
-
const commentRanges =
|
|
3157
|
+
const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
3355
3158
|
if (commentRanges) {
|
|
3356
3159
|
for (const range of commentRanges) {
|
|
3357
|
-
if (range.kind !==
|
|
3160
|
+
if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) continue;
|
|
3358
3161
|
const commentText = sourceText.substring(range.pos, range.end);
|
|
3359
3162
|
if (!commentText.startsWith("/**")) continue;
|
|
3360
3163
|
const unified = parseUnifiedComment(commentText);
|
|
@@ -3379,7 +3182,7 @@ function extractDisplayNameMetadata(node) {
|
|
|
3379
3182
|
}
|
|
3380
3183
|
function collectRawTextFallbacks(node, file) {
|
|
3381
3184
|
const fallbacks = /* @__PURE__ */ new Map();
|
|
3382
|
-
for (const tag of
|
|
3185
|
+
for (const tag of ts3.getJSDocTags(node)) {
|
|
3383
3186
|
const tagName = normalizeConstraintTagName2(tag.tagName.text);
|
|
3384
3187
|
if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
3385
3188
|
const commentText = getTagCommentText(tag)?.trim() ?? "";
|
|
@@ -3434,15 +3237,15 @@ function getTagCommentText(tag) {
|
|
|
3434
3237
|
if (typeof tag.comment === "string") {
|
|
3435
3238
|
return tag.comment;
|
|
3436
3239
|
}
|
|
3437
|
-
return
|
|
3240
|
+
return ts3.getTextOfJSDocComment(tag.comment);
|
|
3438
3241
|
}
|
|
3439
|
-
var
|
|
3242
|
+
var TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
|
|
3440
3243
|
var init_tsdoc_parser = __esm({
|
|
3441
3244
|
"src/analyzer/tsdoc-parser.ts"() {
|
|
3442
3245
|
"use strict";
|
|
3443
3246
|
init_resolve_custom_type();
|
|
3444
3247
|
init_builtin_brands();
|
|
3445
|
-
|
|
3248
|
+
TYPE_FORMAT_FLAGS = ts3.TypeFormatFlags.NoTruncation | ts3.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
3446
3249
|
MAX_HINT_CANDIDATES = 5;
|
|
3447
3250
|
MAX_HINT_DEPTH = 3;
|
|
3448
3251
|
parseResultCache = /* @__PURE__ */ new Map();
|
|
@@ -3450,7 +3253,7 @@ var init_tsdoc_parser = __esm({
|
|
|
3450
3253
|
});
|
|
3451
3254
|
|
|
3452
3255
|
// src/analyzer/jsdoc-constraints.ts
|
|
3453
|
-
import * as
|
|
3256
|
+
import * as ts4 from "typescript";
|
|
3454
3257
|
function extractJSDocParseResult(node, file = "", options) {
|
|
3455
3258
|
return parseTSDocTags(node, file, options);
|
|
3456
3259
|
}
|
|
@@ -3465,18 +3268,18 @@ function extractJSDocAnnotationNodes(node, file = "", options) {
|
|
|
3465
3268
|
function extractDefaultValueAnnotation(initializer, file = "") {
|
|
3466
3269
|
if (!initializer) return null;
|
|
3467
3270
|
let value;
|
|
3468
|
-
if (
|
|
3271
|
+
if (ts4.isStringLiteral(initializer)) {
|
|
3469
3272
|
value = initializer.text;
|
|
3470
|
-
} else if (
|
|
3273
|
+
} else if (ts4.isNumericLiteral(initializer)) {
|
|
3471
3274
|
value = Number(initializer.text);
|
|
3472
|
-
} else if (initializer.kind ===
|
|
3275
|
+
} else if (initializer.kind === ts4.SyntaxKind.TrueKeyword) {
|
|
3473
3276
|
value = true;
|
|
3474
|
-
} else if (initializer.kind ===
|
|
3277
|
+
} else if (initializer.kind === ts4.SyntaxKind.FalseKeyword) {
|
|
3475
3278
|
value = false;
|
|
3476
|
-
} else if (initializer.kind ===
|
|
3279
|
+
} else if (initializer.kind === ts4.SyntaxKind.NullKeyword) {
|
|
3477
3280
|
value = null;
|
|
3478
|
-
} else if (
|
|
3479
|
-
if (initializer.operator ===
|
|
3281
|
+
} else if (ts4.isPrefixUnaryExpression(initializer)) {
|
|
3282
|
+
if (initializer.operator === ts4.SyntaxKind.MinusToken && ts4.isNumericLiteral(initializer.operand)) {
|
|
3480
3283
|
value = -Number(initializer.operand.text);
|
|
3481
3284
|
}
|
|
3482
3285
|
}
|
|
@@ -3503,34 +3306,34 @@ var init_jsdoc_constraints = __esm({
|
|
|
3503
3306
|
});
|
|
3504
3307
|
|
|
3505
3308
|
// src/analyzer/class-analyzer.ts
|
|
3506
|
-
import * as
|
|
3309
|
+
import * as ts5 from "typescript";
|
|
3507
3310
|
import {
|
|
3508
3311
|
analyzeMetadataForNodeWithChecker,
|
|
3509
3312
|
parseCommentBlock
|
|
3510
3313
|
} from "@formspec/analysis/internal";
|
|
3511
3314
|
function isObjectType(type) {
|
|
3512
|
-
return !!(type.flags &
|
|
3315
|
+
return !!(type.flags & ts5.TypeFlags.Object);
|
|
3513
3316
|
}
|
|
3514
3317
|
function isIntersectionType(type) {
|
|
3515
|
-
return !!(type.flags &
|
|
3318
|
+
return !!(type.flags & ts5.TypeFlags.Intersection);
|
|
3516
3319
|
}
|
|
3517
3320
|
function isResolvableObjectLikeAliasTypeNode(typeNode) {
|
|
3518
|
-
if (
|
|
3321
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
3519
3322
|
return isResolvableObjectLikeAliasTypeNode(typeNode.type);
|
|
3520
3323
|
}
|
|
3521
|
-
if (
|
|
3324
|
+
if (ts5.isTypeLiteralNode(typeNode) || ts5.isTypeReferenceNode(typeNode)) {
|
|
3522
3325
|
return true;
|
|
3523
3326
|
}
|
|
3524
|
-
return
|
|
3327
|
+
return ts5.isIntersectionTypeNode(typeNode) && typeNode.types.length > 0 && typeNode.types.every((member) => isResolvableObjectLikeAliasTypeNode(member));
|
|
3525
3328
|
}
|
|
3526
3329
|
function isSemanticallyPlainObjectLikeType(type, checker) {
|
|
3527
3330
|
if (isIntersectionType(type)) {
|
|
3528
3331
|
return type.types.length > 0 && type.types.every((member) => isSemanticallyPlainObjectLikeType(member, checker));
|
|
3529
3332
|
}
|
|
3530
|
-
return isObjectType(type) && checker.getSignaturesOfType(type,
|
|
3333
|
+
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);
|
|
3531
3334
|
}
|
|
3532
3335
|
function isTypeReference(type) {
|
|
3533
|
-
return !!(type.flags &
|
|
3336
|
+
return !!(type.flags & ts5.TypeFlags.Object) && !!(type.objectFlags & ts5.ObjectFlags.Reference);
|
|
3534
3337
|
}
|
|
3535
3338
|
function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, hostType) {
|
|
3536
3339
|
if (extensionRegistry === void 0 && fieldType === void 0 && checker === void 0 && subjectType === void 0 && hostType === void 0) {
|
|
@@ -3551,6 +3354,17 @@ function createAnalyzerMetadataPolicy(input, discriminator) {
|
|
|
3551
3354
|
discriminator
|
|
3552
3355
|
};
|
|
3553
3356
|
}
|
|
3357
|
+
function deduplicateDiagnostics(diagnostics) {
|
|
3358
|
+
if (diagnostics.length <= 1) return diagnostics;
|
|
3359
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3360
|
+
return diagnostics.filter((d) => {
|
|
3361
|
+
if (!DEDUPLICATABLE_DIAGNOSTIC_CODES.has(d.code)) return true;
|
|
3362
|
+
const key = `${d.code}\0${d.message}`;
|
|
3363
|
+
if (seen.has(key)) return false;
|
|
3364
|
+
seen.add(key);
|
|
3365
|
+
return true;
|
|
3366
|
+
});
|
|
3367
|
+
}
|
|
3554
3368
|
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
3555
3369
|
const analysis = analyzeMetadataForNodeWithChecker({
|
|
3556
3370
|
checker,
|
|
@@ -3587,10 +3401,120 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
|
|
|
3587
3401
|
}
|
|
3588
3402
|
return resolvedMetadata;
|
|
3589
3403
|
}
|
|
3404
|
+
function getInheritableAnnotationStringValue(annotation) {
|
|
3405
|
+
if (annotation.annotationKind === "format") return annotation.value;
|
|
3406
|
+
return void 0;
|
|
3407
|
+
}
|
|
3408
|
+
function isOverridingInheritableAnnotation(annotation) {
|
|
3409
|
+
const value = getInheritableAnnotationStringValue(annotation);
|
|
3410
|
+
if (value === void 0) return true;
|
|
3411
|
+
return value.trim().length > 0;
|
|
3412
|
+
}
|
|
3413
|
+
function collectInheritedTypeAnnotations(derivedDecl, existingAnnotations, checker, extensionRegistry) {
|
|
3414
|
+
const existingKinds = new Set(
|
|
3415
|
+
existingAnnotations.filter(isOverridingInheritableAnnotation).map((a) => a.annotationKind)
|
|
3416
|
+
);
|
|
3417
|
+
const needed = /* @__PURE__ */ new Set();
|
|
3418
|
+
for (const kind of INHERITABLE_TYPE_ANNOTATION_KINDS) {
|
|
3419
|
+
if (!existingKinds.has(kind)) needed.add(kind);
|
|
3420
|
+
}
|
|
3421
|
+
if (needed.size === 0) return [];
|
|
3422
|
+
const inherited = [];
|
|
3423
|
+
const seen = /* @__PURE__ */ new Set([derivedDecl]);
|
|
3424
|
+
const queue = [];
|
|
3425
|
+
const resolveSymbolTarget = (sym) => {
|
|
3426
|
+
if ((sym.flags & ts5.SymbolFlags.Alias) === 0) return sym;
|
|
3427
|
+
try {
|
|
3428
|
+
return checker.getAliasedSymbol(sym);
|
|
3429
|
+
} catch {
|
|
3430
|
+
return sym;
|
|
3431
|
+
}
|
|
3432
|
+
};
|
|
3433
|
+
const isObjectShapedTypeAlias = (alias) => {
|
|
3434
|
+
const type = checker.getTypeFromTypeNode(alias.type);
|
|
3435
|
+
if ((type.flags & ts5.TypeFlags.Object) !== 0) return true;
|
|
3436
|
+
if (type.isIntersection()) return true;
|
|
3437
|
+
return false;
|
|
3438
|
+
};
|
|
3439
|
+
const enqueueCandidate = (baseDecl, fromTypeAliasRhs) => {
|
|
3440
|
+
if (seen.has(baseDecl)) return;
|
|
3441
|
+
if (ts5.isClassDeclaration(baseDecl) || ts5.isInterfaceDeclaration(baseDecl)) {
|
|
3442
|
+
seen.add(baseDecl);
|
|
3443
|
+
queue.push(baseDecl);
|
|
3444
|
+
return;
|
|
3445
|
+
}
|
|
3446
|
+
if (ts5.isTypeAliasDeclaration(baseDecl)) {
|
|
3447
|
+
if (!fromTypeAliasRhs && !isObjectShapedTypeAlias(baseDecl)) return;
|
|
3448
|
+
seen.add(baseDecl);
|
|
3449
|
+
queue.push(baseDecl);
|
|
3450
|
+
}
|
|
3451
|
+
};
|
|
3452
|
+
const enqueueBasesOf = (decl) => {
|
|
3453
|
+
if (ts5.isTypeAliasDeclaration(decl)) {
|
|
3454
|
+
const rhs = decl.type;
|
|
3455
|
+
if (!ts5.isTypeReferenceNode(rhs)) return;
|
|
3456
|
+
const sym = checker.getSymbolAtLocation(rhs.typeName);
|
|
3457
|
+
if (!sym) return;
|
|
3458
|
+
const target = resolveSymbolTarget(sym);
|
|
3459
|
+
for (const baseDecl of target.declarations ?? []) {
|
|
3460
|
+
enqueueCandidate(
|
|
3461
|
+
baseDecl,
|
|
3462
|
+
/*fromTypeAliasRhs*/
|
|
3463
|
+
true
|
|
3464
|
+
);
|
|
3465
|
+
}
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
const heritageClauses = decl.heritageClauses;
|
|
3469
|
+
if (!heritageClauses) return;
|
|
3470
|
+
for (const clause of heritageClauses) {
|
|
3471
|
+
if (clause.token !== ts5.SyntaxKind.ExtendsKeyword) continue;
|
|
3472
|
+
for (const typeExpr of clause.types) {
|
|
3473
|
+
const sym = checker.getSymbolAtLocation(typeExpr.expression);
|
|
3474
|
+
if (!sym) continue;
|
|
3475
|
+
const target = resolveSymbolTarget(sym);
|
|
3476
|
+
for (const baseDecl of target.declarations ?? []) {
|
|
3477
|
+
enqueueCandidate(
|
|
3478
|
+
baseDecl,
|
|
3479
|
+
/*fromTypeAliasRhs*/
|
|
3480
|
+
false
|
|
3481
|
+
);
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
};
|
|
3486
|
+
enqueueBasesOf(derivedDecl);
|
|
3487
|
+
for (let queueIndex = 0; queueIndex < queue.length && needed.size > 0; queueIndex++) {
|
|
3488
|
+
const baseDecl = queue[queueIndex];
|
|
3489
|
+
if (baseDecl === void 0) continue;
|
|
3490
|
+
const baseFile = baseDecl.getSourceFile().fileName;
|
|
3491
|
+
const baseAnnotations = extractJSDocAnnotationNodes(
|
|
3492
|
+
baseDecl,
|
|
3493
|
+
baseFile,
|
|
3494
|
+
makeParseOptions(extensionRegistry)
|
|
3495
|
+
);
|
|
3496
|
+
for (const annotation of baseAnnotations) {
|
|
3497
|
+
if (!needed.has(annotation.annotationKind)) continue;
|
|
3498
|
+
if (!isOverridingInheritableAnnotation(annotation)) continue;
|
|
3499
|
+
inherited.push(annotation);
|
|
3500
|
+
needed.delete(annotation.annotationKind);
|
|
3501
|
+
}
|
|
3502
|
+
if (needed.size > 0) {
|
|
3503
|
+
enqueueBasesOf(baseDecl);
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
return inherited;
|
|
3507
|
+
}
|
|
3508
|
+
function extractNamedTypeAnnotations(namedDecl, checker, file, extensionRegistry) {
|
|
3509
|
+
const local = extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry));
|
|
3510
|
+
const inherited = collectInheritedTypeAnnotations(namedDecl, local, checker, extensionRegistry);
|
|
3511
|
+
if (inherited.length === 0) return [...local];
|
|
3512
|
+
return [...local, ...inherited];
|
|
3513
|
+
}
|
|
3590
3514
|
function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
3591
3515
|
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
3592
3516
|
const declarationType = checker.getTypeAtLocation(declaration);
|
|
3593
|
-
const logicalName =
|
|
3517
|
+
const logicalName = ts5.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
|
|
3594
3518
|
const docResult = extractJSDocParseResult(
|
|
3595
3519
|
declaration,
|
|
3596
3520
|
file,
|
|
@@ -3632,13 +3556,19 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3632
3556
|
file,
|
|
3633
3557
|
makeParseOptions(extensionRegistry, void 0, checker, classType, classType)
|
|
3634
3558
|
);
|
|
3635
|
-
const
|
|
3559
|
+
const inheritedClassAnnotations = collectInheritedTypeAnnotations(
|
|
3560
|
+
classDecl,
|
|
3561
|
+
classDoc.annotations,
|
|
3562
|
+
checker,
|
|
3563
|
+
extensionRegistry
|
|
3564
|
+
);
|
|
3565
|
+
const annotations = [...classDoc.annotations, ...inheritedClassAnnotations];
|
|
3636
3566
|
diagnostics.push(...classDoc.diagnostics);
|
|
3637
3567
|
const visiting = /* @__PURE__ */ new Set();
|
|
3638
3568
|
const instanceMethods = [];
|
|
3639
3569
|
const staticMethods = [];
|
|
3640
3570
|
for (const member of classDecl.members) {
|
|
3641
|
-
if (
|
|
3571
|
+
if (ts5.isPropertyDeclaration(member)) {
|
|
3642
3572
|
const fieldNode = analyzeFieldToIR(
|
|
3643
3573
|
member,
|
|
3644
3574
|
checker,
|
|
@@ -3654,10 +3584,10 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3654
3584
|
fields.push(fieldNode);
|
|
3655
3585
|
fieldLayouts.push({});
|
|
3656
3586
|
}
|
|
3657
|
-
} else if (
|
|
3587
|
+
} else if (ts5.isMethodDeclaration(member)) {
|
|
3658
3588
|
const methodInfo = analyzeMethod(member, checker);
|
|
3659
3589
|
if (methodInfo) {
|
|
3660
|
-
const isStatic = member.modifiers?.some((m) => m.kind ===
|
|
3590
|
+
const isStatic = member.modifiers?.some((m) => m.kind === ts5.SyntaxKind.StaticKeyword);
|
|
3661
3591
|
if (isStatic) {
|
|
3662
3592
|
staticMethods.push(methodInfo);
|
|
3663
3593
|
} else {
|
|
@@ -3689,6 +3619,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3689
3619
|
hostType: classType
|
|
3690
3620
|
}
|
|
3691
3621
|
);
|
|
3622
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
3692
3623
|
return {
|
|
3693
3624
|
name,
|
|
3694
3625
|
...metadata !== void 0 && { metadata },
|
|
@@ -3696,7 +3627,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3696
3627
|
fieldLayouts,
|
|
3697
3628
|
typeRegistry,
|
|
3698
3629
|
...annotations.length > 0 && { annotations },
|
|
3699
|
-
...
|
|
3630
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
3700
3631
|
instanceMethods,
|
|
3701
3632
|
staticMethods
|
|
3702
3633
|
};
|
|
@@ -3716,11 +3647,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3716
3647
|
file,
|
|
3717
3648
|
makeParseOptions(extensionRegistry, void 0, checker, interfaceType, interfaceType)
|
|
3718
3649
|
);
|
|
3719
|
-
const
|
|
3650
|
+
const inheritedInterfaceAnnotations = collectInheritedTypeAnnotations(
|
|
3651
|
+
interfaceDecl,
|
|
3652
|
+
interfaceDoc.annotations,
|
|
3653
|
+
checker,
|
|
3654
|
+
extensionRegistry
|
|
3655
|
+
);
|
|
3656
|
+
const annotations = [
|
|
3657
|
+
...interfaceDoc.annotations,
|
|
3658
|
+
...inheritedInterfaceAnnotations
|
|
3659
|
+
];
|
|
3720
3660
|
diagnostics.push(...interfaceDoc.diagnostics);
|
|
3721
3661
|
const visiting = /* @__PURE__ */ new Set();
|
|
3722
3662
|
for (const member of interfaceDecl.members) {
|
|
3723
|
-
if (
|
|
3663
|
+
if (ts5.isPropertySignature(member)) {
|
|
3724
3664
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
3725
3665
|
member,
|
|
3726
3666
|
checker,
|
|
@@ -3761,6 +3701,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3761
3701
|
hostType: interfaceType
|
|
3762
3702
|
}
|
|
3763
3703
|
);
|
|
3704
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
3764
3705
|
return {
|
|
3765
3706
|
name,
|
|
3766
3707
|
...metadata !== void 0 && { metadata },
|
|
@@ -3768,7 +3709,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3768
3709
|
fieldLayouts,
|
|
3769
3710
|
typeRegistry,
|
|
3770
3711
|
...annotations.length > 0 && { annotations },
|
|
3771
|
-
...
|
|
3712
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
3772
3713
|
instanceMethods: [],
|
|
3773
3714
|
staticMethods: []
|
|
3774
3715
|
};
|
|
@@ -3778,7 +3719,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3778
3719
|
if (members === null) {
|
|
3779
3720
|
const sourceFile = typeAlias.getSourceFile();
|
|
3780
3721
|
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
3781
|
-
const kindDesc =
|
|
3722
|
+
const kindDesc = ts5.SyntaxKind[typeAlias.type.kind] ?? "unknown";
|
|
3782
3723
|
return {
|
|
3783
3724
|
ok: false,
|
|
3784
3725
|
kind: "not-object-like",
|
|
@@ -3813,7 +3754,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3813
3754
|
diagnostics.push(...typeAliasDoc.diagnostics);
|
|
3814
3755
|
const visiting = /* @__PURE__ */ new Set();
|
|
3815
3756
|
for (const member of members) {
|
|
3816
|
-
if (
|
|
3757
|
+
if (ts5.isPropertySignature(member)) {
|
|
3817
3758
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
3818
3759
|
member,
|
|
3819
3760
|
checker,
|
|
@@ -3853,6 +3794,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3853
3794
|
hostType: aliasType
|
|
3854
3795
|
}
|
|
3855
3796
|
);
|
|
3797
|
+
const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
|
|
3856
3798
|
return {
|
|
3857
3799
|
ok: true,
|
|
3858
3800
|
analysis: {
|
|
@@ -3862,7 +3804,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3862
3804
|
fieldLayouts: specializedFields.map(() => ({})),
|
|
3863
3805
|
typeRegistry,
|
|
3864
3806
|
...annotations.length > 0 && { annotations },
|
|
3865
|
-
...
|
|
3807
|
+
...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
|
|
3866
3808
|
instanceMethods: [],
|
|
3867
3809
|
staticMethods: []
|
|
3868
3810
|
}
|
|
@@ -3880,13 +3822,13 @@ function makeAnalysisDiagnostic(code, message, primaryLocation, relatedLocations
|
|
|
3880
3822
|
function getLeadingParsedTags(node) {
|
|
3881
3823
|
const sourceFile = node.getSourceFile();
|
|
3882
3824
|
const sourceText = sourceFile.getFullText();
|
|
3883
|
-
const commentRanges =
|
|
3825
|
+
const commentRanges = ts5.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
3884
3826
|
if (commentRanges === void 0) {
|
|
3885
3827
|
return [];
|
|
3886
3828
|
}
|
|
3887
3829
|
const parsedTags = [];
|
|
3888
3830
|
for (const range of commentRanges) {
|
|
3889
|
-
if (range.kind !==
|
|
3831
|
+
if (range.kind !== ts5.SyntaxKind.MultiLineCommentTrivia) {
|
|
3890
3832
|
continue;
|
|
3891
3833
|
}
|
|
3892
3834
|
const commentText = sourceText.slice(range.pos, range.end);
|
|
@@ -3904,19 +3846,19 @@ function resolveDiscriminatorProperty(node, checker, fieldName) {
|
|
|
3904
3846
|
return null;
|
|
3905
3847
|
}
|
|
3906
3848
|
const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.find(
|
|
3907
|
-
(candidate) =>
|
|
3849
|
+
(candidate) => ts5.isPropertyDeclaration(candidate) || ts5.isPropertySignature(candidate)
|
|
3908
3850
|
) ?? propertySymbol.declarations?.[0];
|
|
3909
3851
|
return {
|
|
3910
3852
|
declaration,
|
|
3911
3853
|
type: checker.getTypeOfSymbolAtLocation(propertySymbol, declaration ?? node),
|
|
3912
|
-
optional: !!(propertySymbol.flags &
|
|
3854
|
+
optional: !!(propertySymbol.flags & ts5.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
|
|
3913
3855
|
};
|
|
3914
3856
|
}
|
|
3915
3857
|
function isLocalTypeParameterName(node, typeParameterName) {
|
|
3916
3858
|
return node.typeParameters?.some((typeParameter) => typeParameter.name.text === typeParameterName) ?? false;
|
|
3917
3859
|
}
|
|
3918
3860
|
function isNullishSemanticType(type) {
|
|
3919
|
-
if (type.flags & (
|
|
3861
|
+
if (type.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined | ts5.TypeFlags.Void | ts5.TypeFlags.Unknown | ts5.TypeFlags.Any)) {
|
|
3920
3862
|
return true;
|
|
3921
3863
|
}
|
|
3922
3864
|
return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
|
|
@@ -3926,7 +3868,7 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
|
|
|
3926
3868
|
return false;
|
|
3927
3869
|
}
|
|
3928
3870
|
seen.add(type);
|
|
3929
|
-
if (type.flags &
|
|
3871
|
+
if (type.flags & ts5.TypeFlags.StringLike) {
|
|
3930
3872
|
return true;
|
|
3931
3873
|
}
|
|
3932
3874
|
if (type.isUnion()) {
|
|
@@ -3939,13 +3881,13 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
|
|
|
3939
3881
|
return false;
|
|
3940
3882
|
}
|
|
3941
3883
|
function getObjectLikeTypeAliasMembers(typeNode) {
|
|
3942
|
-
if (
|
|
3884
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
3943
3885
|
return getObjectLikeTypeAliasMembers(typeNode.type);
|
|
3944
3886
|
}
|
|
3945
|
-
if (
|
|
3887
|
+
if (ts5.isTypeLiteralNode(typeNode)) {
|
|
3946
3888
|
return [...typeNode.members];
|
|
3947
3889
|
}
|
|
3948
|
-
if (
|
|
3890
|
+
if (ts5.isIntersectionTypeNode(typeNode)) {
|
|
3949
3891
|
const members = [];
|
|
3950
3892
|
for (const intersectionMember of typeNode.types) {
|
|
3951
3893
|
const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
|
|
@@ -4108,7 +4050,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, check
|
|
|
4108
4050
|
}
|
|
4109
4051
|
if (propertyType.isUnion()) {
|
|
4110
4052
|
const nonNullMembers = propertyType.types.filter(
|
|
4111
|
-
(member) => !(member.flags & (
|
|
4053
|
+
(member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
4112
4054
|
);
|
|
4113
4055
|
if (nonNullMembers.length > 0 && nonNullMembers.every((member) => member.isStringLiteral())) {
|
|
4114
4056
|
diagnostics.push(
|
|
@@ -4157,13 +4099,13 @@ function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__
|
|
|
4157
4099
|
seen.add(type);
|
|
4158
4100
|
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
4159
4101
|
if (symbol !== void 0) {
|
|
4160
|
-
const aliased = symbol.flags &
|
|
4102
|
+
const aliased = symbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : void 0;
|
|
4161
4103
|
const targetSymbol = aliased ?? symbol;
|
|
4162
4104
|
const declaration = targetSymbol.declarations?.find(
|
|
4163
|
-
(candidate) =>
|
|
4105
|
+
(candidate) => ts5.isClassDeclaration(candidate) || ts5.isInterfaceDeclaration(candidate) || ts5.isTypeAliasDeclaration(candidate) || ts5.isEnumDeclaration(candidate)
|
|
4164
4106
|
);
|
|
4165
4107
|
if (declaration !== void 0) {
|
|
4166
|
-
if (
|
|
4108
|
+
if (ts5.isTypeAliasDeclaration(declaration) && ts5.isTypeReferenceNode(declaration.type) && checker.getTypeFromTypeNode(declaration.type) !== type) {
|
|
4167
4109
|
return resolveNamedDiscriminatorDeclaration(
|
|
4168
4110
|
checker.getTypeFromTypeNode(declaration.type),
|
|
4169
4111
|
checker,
|
|
@@ -4191,7 +4133,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
|
|
|
4191
4133
|
}
|
|
4192
4134
|
if (boundType.isUnion()) {
|
|
4193
4135
|
const nonNullMembers = boundType.types.filter(
|
|
4194
|
-
(member) => !(member.flags & (
|
|
4136
|
+
(member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
4195
4137
|
);
|
|
4196
4138
|
if (nonNullMembers.every((member) => member.isStringLiteral())) {
|
|
4197
4139
|
diagnostics.push(
|
|
@@ -4236,7 +4178,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
|
|
|
4236
4178
|
return null;
|
|
4237
4179
|
}
|
|
4238
4180
|
function getDeclarationName(node) {
|
|
4239
|
-
if (
|
|
4181
|
+
if (ts5.isClassDeclaration(node) || ts5.isInterfaceDeclaration(node) || ts5.isTypeAliasDeclaration(node) || ts5.isEnumDeclaration(node)) {
|
|
4240
4182
|
return node.name?.text ?? "anonymous";
|
|
4241
4183
|
}
|
|
4242
4184
|
return "anonymous";
|
|
@@ -4291,11 +4233,11 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
4291
4233
|
if (sourceTypeNode === void 0) {
|
|
4292
4234
|
return [];
|
|
4293
4235
|
}
|
|
4294
|
-
const unwrapParentheses = (typeNode) =>
|
|
4236
|
+
const unwrapParentheses = (typeNode) => ts5.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
|
|
4295
4237
|
const directTypeNode = unwrapParentheses(sourceTypeNode);
|
|
4296
|
-
const referenceTypeNode =
|
|
4238
|
+
const referenceTypeNode = ts5.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
|
|
4297
4239
|
const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
|
|
4298
|
-
return
|
|
4240
|
+
return ts5.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
|
|
4299
4241
|
})();
|
|
4300
4242
|
if (referenceTypeNode?.typeArguments === void 0) {
|
|
4301
4243
|
return [];
|
|
@@ -4303,7 +4245,7 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
4303
4245
|
return referenceTypeNode.typeArguments.map((argumentNode) => {
|
|
4304
4246
|
const argumentType = checker.getTypeFromTypeNode(argumentNode);
|
|
4305
4247
|
const baseSymbol = argumentType.aliasSymbol ?? argumentType.getSymbol();
|
|
4306
|
-
const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags &
|
|
4248
|
+
const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(baseSymbol) : baseSymbol;
|
|
4307
4249
|
const argumentDecl = argumentSymbol?.declarations?.[0];
|
|
4308
4250
|
if (argumentDecl !== void 0 && argumentDecl.getSourceFile().fileName !== file) {
|
|
4309
4251
|
const argumentName = argumentSymbol?.getName() ?? baseSymbol?.getName();
|
|
@@ -4366,7 +4308,7 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
|
|
|
4366
4308
|
);
|
|
4367
4309
|
}
|
|
4368
4310
|
function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
4369
|
-
if (!
|
|
4311
|
+
if (!ts5.isIdentifier(prop.name)) {
|
|
4370
4312
|
return null;
|
|
4371
4313
|
}
|
|
4372
4314
|
const name = prop.name.text;
|
|
@@ -4493,7 +4435,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
|
|
|
4493
4435
|
const seen = /* @__PURE__ */ new Set();
|
|
4494
4436
|
const duplicates = /* @__PURE__ */ new Set();
|
|
4495
4437
|
for (const member of members) {
|
|
4496
|
-
if (!
|
|
4438
|
+
if (!ts5.isPropertySignature(member)) {
|
|
4497
4439
|
continue;
|
|
4498
4440
|
}
|
|
4499
4441
|
const name = getAnalyzableObjectLikePropertyName(member.name);
|
|
@@ -4509,7 +4451,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
|
|
|
4509
4451
|
return [...duplicates].sort();
|
|
4510
4452
|
}
|
|
4511
4453
|
function getAnalyzableObjectLikePropertyName(name) {
|
|
4512
|
-
if (
|
|
4454
|
+
if (ts5.isIdentifier(name) || ts5.isStringLiteral(name) || ts5.isNumericLiteral(name)) {
|
|
4513
4455
|
return name.text;
|
|
4514
4456
|
}
|
|
4515
4457
|
return null;
|
|
@@ -4604,28 +4546,28 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
4604
4546
|
if (primitiveAlias) {
|
|
4605
4547
|
return primitiveAlias;
|
|
4606
4548
|
}
|
|
4607
|
-
if (
|
|
4549
|
+
if (_isIntegerBrandedType(type)) {
|
|
4608
4550
|
return { kind: "primitive", primitiveKind: "integer" };
|
|
4609
4551
|
}
|
|
4610
|
-
if (type.flags &
|
|
4552
|
+
if (type.flags & ts5.TypeFlags.String) {
|
|
4611
4553
|
return { kind: "primitive", primitiveKind: "string" };
|
|
4612
4554
|
}
|
|
4613
|
-
if (type.flags &
|
|
4555
|
+
if (type.flags & ts5.TypeFlags.Number) {
|
|
4614
4556
|
return { kind: "primitive", primitiveKind: "number" };
|
|
4615
4557
|
}
|
|
4616
|
-
if (type.flags & (
|
|
4558
|
+
if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
|
|
4617
4559
|
return { kind: "primitive", primitiveKind: "bigint" };
|
|
4618
4560
|
}
|
|
4619
|
-
if (type.flags &
|
|
4561
|
+
if (type.flags & ts5.TypeFlags.Boolean) {
|
|
4620
4562
|
return { kind: "primitive", primitiveKind: "boolean" };
|
|
4621
4563
|
}
|
|
4622
|
-
if (type.flags &
|
|
4564
|
+
if (type.flags & ts5.TypeFlags.Null) {
|
|
4623
4565
|
return { kind: "primitive", primitiveKind: "null" };
|
|
4624
4566
|
}
|
|
4625
|
-
if (type.flags &
|
|
4567
|
+
if (type.flags & ts5.TypeFlags.Undefined) {
|
|
4626
4568
|
return { kind: "primitive", primitiveKind: "null" };
|
|
4627
4569
|
}
|
|
4628
|
-
if (type.flags &
|
|
4570
|
+
if (type.flags & ts5.TypeFlags.Void) {
|
|
4629
4571
|
return { kind: "primitive", primitiveKind: "null" };
|
|
4630
4572
|
}
|
|
4631
4573
|
if (type.isStringLiteral()) {
|
|
@@ -4712,10 +4654,10 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
4712
4654
|
return { kind: "primitive", primitiveKind: "string" };
|
|
4713
4655
|
}
|
|
4714
4656
|
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4715
|
-
if (!(type.flags & (
|
|
4657
|
+
if (!(type.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null)) && !_isIntegerBrandedType(type)) {
|
|
4716
4658
|
return null;
|
|
4717
4659
|
}
|
|
4718
|
-
const aliasDecl = type.aliasSymbol?.declarations?.find(
|
|
4660
|
+
const aliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration) ?? getReferencedTypeAliasDeclaration(sourceNode, checker);
|
|
4719
4661
|
if (!aliasDecl) {
|
|
4720
4662
|
return null;
|
|
4721
4663
|
}
|
|
@@ -4726,11 +4668,18 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
4726
4668
|
...extractJSDocConstraintNodes(aliasDecl, file, makeParseOptions(extensionRegistry)),
|
|
4727
4669
|
...extractTypeAliasConstraintNodes(aliasDecl.type, checker, file, extensionRegistry)
|
|
4728
4670
|
];
|
|
4729
|
-
const
|
|
4671
|
+
const localAnnotations = extractJSDocAnnotationNodes(
|
|
4730
4672
|
aliasDecl,
|
|
4731
4673
|
file,
|
|
4732
4674
|
makeParseOptions(extensionRegistry)
|
|
4733
4675
|
);
|
|
4676
|
+
const inheritedAnnotations = collectInheritedTypeAnnotations(
|
|
4677
|
+
aliasDecl,
|
|
4678
|
+
localAnnotations,
|
|
4679
|
+
checker,
|
|
4680
|
+
extensionRegistry
|
|
4681
|
+
);
|
|
4682
|
+
const annotations = [...localAnnotations, ...inheritedAnnotations];
|
|
4734
4683
|
const metadata = resolveNodeMetadata(
|
|
4735
4684
|
metadataPolicy,
|
|
4736
4685
|
"type",
|
|
@@ -4765,8 +4714,8 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
4765
4714
|
return { kind: "reference", name: aliasName, typeArguments: [] };
|
|
4766
4715
|
}
|
|
4767
4716
|
function getReferencedTypeAliasDeclaration(sourceNode, checker) {
|
|
4768
|
-
const typeNode = sourceNode && (
|
|
4769
|
-
if (!typeNode || !
|
|
4717
|
+
const typeNode = sourceNode && (ts5.isPropertyDeclaration(sourceNode) || ts5.isPropertySignature(sourceNode) || ts5.isParameter(sourceNode)) ? sourceNode.type : void 0;
|
|
4718
|
+
if (!typeNode || !ts5.isTypeReferenceNode(typeNode)) {
|
|
4770
4719
|
return void 0;
|
|
4771
4720
|
}
|
|
4772
4721
|
return getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -4787,7 +4736,7 @@ function resolveNamedTypeWithSourceRecovery(type, sourceNode, checker) {
|
|
|
4787
4736
|
return { typeName: refAliasDecl.name.text, namedDecl: refAliasDecl };
|
|
4788
4737
|
}
|
|
4789
4738
|
function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
4790
|
-
if (!
|
|
4739
|
+
if (!ts5.isTypeReferenceNode(typeNode)) {
|
|
4791
4740
|
return false;
|
|
4792
4741
|
}
|
|
4793
4742
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -4795,10 +4744,10 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
4795
4744
|
return false;
|
|
4796
4745
|
}
|
|
4797
4746
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
4798
|
-
return !!(resolved.flags & (
|
|
4747
|
+
return !!(resolved.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null));
|
|
4799
4748
|
}
|
|
4800
4749
|
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics, visitedAliases = /* @__PURE__ */ new Set()) {
|
|
4801
|
-
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(
|
|
4750
|
+
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration);
|
|
4802
4751
|
if (nestedAliasDecl !== void 0 && !visitedAliases.has(nestedAliasDecl)) {
|
|
4803
4752
|
visitedAliases.add(nestedAliasDecl);
|
|
4804
4753
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -4813,22 +4762,22 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
4813
4762
|
visitedAliases
|
|
4814
4763
|
);
|
|
4815
4764
|
}
|
|
4816
|
-
if (
|
|
4765
|
+
if (_isIntegerBrandedType(type)) {
|
|
4817
4766
|
return { kind: "primitive", primitiveKind: "integer" };
|
|
4818
4767
|
}
|
|
4819
|
-
if (type.flags &
|
|
4768
|
+
if (type.flags & ts5.TypeFlags.String) {
|
|
4820
4769
|
return { kind: "primitive", primitiveKind: "string" };
|
|
4821
4770
|
}
|
|
4822
|
-
if (type.flags &
|
|
4771
|
+
if (type.flags & ts5.TypeFlags.Number) {
|
|
4823
4772
|
return { kind: "primitive", primitiveKind: "number" };
|
|
4824
4773
|
}
|
|
4825
|
-
if (type.flags & (
|
|
4774
|
+
if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
|
|
4826
4775
|
return { kind: "primitive", primitiveKind: "bigint" };
|
|
4827
4776
|
}
|
|
4828
|
-
if (type.flags &
|
|
4777
|
+
if (type.flags & ts5.TypeFlags.Boolean) {
|
|
4829
4778
|
return { kind: "primitive", primitiveKind: "boolean" };
|
|
4830
4779
|
}
|
|
4831
|
-
if (type.flags &
|
|
4780
|
+
if (type.flags & ts5.TypeFlags.Null) {
|
|
4832
4781
|
return { kind: "primitive", primitiveKind: "null" };
|
|
4833
4782
|
}
|
|
4834
4783
|
return resolveTypeNode(
|
|
@@ -4848,7 +4797,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4848
4797
|
let typeName = null;
|
|
4849
4798
|
let namedDecl;
|
|
4850
4799
|
if (recovered !== null) {
|
|
4851
|
-
const recoveredAliasDecl =
|
|
4800
|
+
const recoveredAliasDecl = ts5.isTypeAliasDeclaration(recovered.namedDecl) ? recovered.namedDecl : void 0;
|
|
4852
4801
|
if (recoveredAliasDecl !== void 0) {
|
|
4853
4802
|
const aliasUnderlyingType = checker.getTypeFromTypeNode(recoveredAliasDecl.type);
|
|
4854
4803
|
const isNonGeneric = recoveredAliasDecl.typeParameters === void 0 || recoveredAliasDecl.typeParameters.length === 0;
|
|
@@ -4870,13 +4819,13 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4870
4819
|
(memberTypeNode) => !isNullishTypeNode(resolveAliasedTypeNode(memberTypeNode, checker))
|
|
4871
4820
|
);
|
|
4872
4821
|
const nonNullTypes = allTypes.filter(
|
|
4873
|
-
(memberType) => !(memberType.flags & (
|
|
4822
|
+
(memberType) => !(memberType.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
|
|
4874
4823
|
);
|
|
4875
4824
|
const nonNullMembers = nonNullTypes.map((memberType, index) => ({
|
|
4876
4825
|
memberType,
|
|
4877
4826
|
sourceNode: nonNullSourceNodes.length === nonNullTypes.length ? nonNullSourceNodes[index] : void 0
|
|
4878
4827
|
}));
|
|
4879
|
-
const hasNull = allTypes.some((t) => t.flags &
|
|
4828
|
+
const hasNull = allTypes.some((t) => t.flags & ts5.TypeFlags.Null);
|
|
4880
4829
|
const memberDisplayNames = /* @__PURE__ */ new Map();
|
|
4881
4830
|
if (namedDecl) {
|
|
4882
4831
|
for (const [value, label] of extractDisplayNameMetadata(namedDecl).memberDisplayNames) {
|
|
@@ -4896,7 +4845,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4896
4845
|
if (existing !== void 0 && existing.type !== RESOLVING_TYPE_PLACEHOLDER) {
|
|
4897
4846
|
return { kind: "reference", name: typeName, typeArguments: [] };
|
|
4898
4847
|
}
|
|
4899
|
-
const annotations = namedDecl ?
|
|
4848
|
+
const annotations = namedDecl ? extractNamedTypeAnnotations(namedDecl, checker, file, extensionRegistry) : void 0;
|
|
4900
4849
|
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4901
4850
|
metadataPolicy,
|
|
4902
4851
|
"type",
|
|
@@ -4923,7 +4872,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4923
4872
|
const displayName = memberDisplayNames.get(String(value));
|
|
4924
4873
|
return displayName !== void 0 ? { value, displayName } : { value };
|
|
4925
4874
|
});
|
|
4926
|
-
const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags &
|
|
4875
|
+
const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags & ts5.TypeFlags.BooleanLiteral);
|
|
4927
4876
|
if (isBooleanUnion2) {
|
|
4928
4877
|
const boolNode = { kind: "primitive", primitiveKind: "boolean" };
|
|
4929
4878
|
const result = hasNull ? {
|
|
@@ -5015,7 +4964,7 @@ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metad
|
|
|
5015
4964
|
if (type.getProperties().length > 0) {
|
|
5016
4965
|
return null;
|
|
5017
4966
|
}
|
|
5018
|
-
const indexInfo = checker.getIndexInfoOfType(type,
|
|
4967
|
+
const indexInfo = checker.getIndexInfoOfType(type, ts5.IndexKind.String);
|
|
5019
4968
|
if (!indexInfo) {
|
|
5020
4969
|
return null;
|
|
5021
4970
|
}
|
|
@@ -5063,20 +5012,53 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
|
5063
5012
|
}
|
|
5064
5013
|
if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
|
|
5065
5014
|
const name = declaration.name;
|
|
5066
|
-
if (
|
|
5015
|
+
if (ts5.isComputedPropertyName(name) || ts5.isPrivateIdentifier(name)) {
|
|
5067
5016
|
return false;
|
|
5068
5017
|
}
|
|
5069
|
-
if (!
|
|
5018
|
+
if (!ts5.isIdentifier(name) && !ts5.isStringLiteral(name) && !ts5.isNumericLiteral(name)) {
|
|
5070
5019
|
return false;
|
|
5071
5020
|
}
|
|
5072
5021
|
}
|
|
5073
5022
|
return true;
|
|
5074
5023
|
}
|
|
5024
|
+
function getPassThroughTypeAliasFromSourceNode(sourceNode, checker, extensionRegistry, resolvedTypeName) {
|
|
5025
|
+
const aliasDecl = getReferencedTypeAliasDeclaration(sourceNode, checker);
|
|
5026
|
+
if (!aliasDecl) return void 0;
|
|
5027
|
+
const aliasName = aliasDecl.name.text;
|
|
5028
|
+
if (aliasName === resolvedTypeName) return void 0;
|
|
5029
|
+
if (!ts5.isTypeReferenceNode(aliasDecl.type)) return void 0;
|
|
5030
|
+
if (!hasInheritableTypeAnnotation(aliasDecl, checker, extensionRegistry)) {
|
|
5031
|
+
return void 0;
|
|
5032
|
+
}
|
|
5033
|
+
return { aliasName, aliasDecl };
|
|
5034
|
+
}
|
|
5035
|
+
function hasInheritableTypeAnnotation(aliasDecl, checker, extensionRegistry) {
|
|
5036
|
+
const file = aliasDecl.getSourceFile().fileName;
|
|
5037
|
+
const local = extractJSDocAnnotationNodes(aliasDecl, file, makeParseOptions(extensionRegistry));
|
|
5038
|
+
for (const annotation of local) {
|
|
5039
|
+
if (!INHERITABLE_TYPE_ANNOTATION_KINDS.has(annotation.annotationKind)) continue;
|
|
5040
|
+
if (!isOverridingInheritableAnnotation(annotation)) continue;
|
|
5041
|
+
return true;
|
|
5042
|
+
}
|
|
5043
|
+
const inherited = collectInheritedTypeAnnotations(aliasDecl, local, checker, extensionRegistry);
|
|
5044
|
+
for (const annotation of inherited) {
|
|
5045
|
+
if (INHERITABLE_TYPE_ANNOTATION_KINDS.has(annotation.annotationKind)) return true;
|
|
5046
|
+
}
|
|
5047
|
+
return false;
|
|
5048
|
+
}
|
|
5075
5049
|
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
5076
5050
|
const collectedDiagnostics = diagnostics ?? [];
|
|
5077
5051
|
const typeName = getNamedTypeName(type);
|
|
5078
5052
|
const namedTypeName = typeName ?? void 0;
|
|
5079
5053
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
5054
|
+
const passThroughAlias = getPassThroughTypeAliasFromSourceNode(
|
|
5055
|
+
sourceNode,
|
|
5056
|
+
checker,
|
|
5057
|
+
extensionRegistry,
|
|
5058
|
+
namedTypeName
|
|
5059
|
+
);
|
|
5060
|
+
const effectiveTypeName = passThroughAlias?.aliasName ?? namedTypeName;
|
|
5061
|
+
const effectiveNamedDecl = passThroughAlias?.aliasDecl ?? namedDecl;
|
|
5080
5062
|
const referenceTypeArguments = extractReferenceTypeArguments(
|
|
5081
5063
|
type,
|
|
5082
5064
|
checker,
|
|
@@ -5088,13 +5070,13 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5088
5070
|
extensionRegistry,
|
|
5089
5071
|
collectedDiagnostics
|
|
5090
5072
|
);
|
|
5091
|
-
const instantiatedTypeName =
|
|
5092
|
-
|
|
5073
|
+
const instantiatedTypeName = effectiveTypeName !== void 0 && referenceTypeArguments.length > 0 ? buildInstantiatedReferenceName(
|
|
5074
|
+
effectiveTypeName,
|
|
5093
5075
|
referenceTypeArguments.map((argument) => argument.tsType),
|
|
5094
5076
|
checker
|
|
5095
5077
|
) : void 0;
|
|
5096
|
-
const registryTypeName = instantiatedTypeName ??
|
|
5097
|
-
const shouldRegisterNamedType = registryTypeName !== void 0 && !(registryTypeName === "Record" &&
|
|
5078
|
+
const registryTypeName = instantiatedTypeName ?? effectiveTypeName;
|
|
5079
|
+
const shouldRegisterNamedType = registryTypeName !== void 0 && !(registryTypeName === "Record" && effectiveNamedDecl?.getSourceFile().fileName !== file);
|
|
5098
5080
|
const clearNamedTypeRegistration = () => {
|
|
5099
5081
|
if (registryTypeName === void 0 || !shouldRegisterNamedType) {
|
|
5100
5082
|
return;
|
|
@@ -5115,7 +5097,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5115
5097
|
typeRegistry[registryTypeName] = {
|
|
5116
5098
|
name: registryTypeName,
|
|
5117
5099
|
type: RESOLVING_TYPE_PLACEHOLDER,
|
|
5118
|
-
provenance: provenanceForDeclaration(
|
|
5100
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
5119
5101
|
};
|
|
5120
5102
|
}
|
|
5121
5103
|
visiting.add(type);
|
|
@@ -5147,17 +5129,17 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5147
5129
|
clearNamedTypeRegistration();
|
|
5148
5130
|
return recordNode;
|
|
5149
5131
|
}
|
|
5150
|
-
const annotations =
|
|
5151
|
-
const metadata =
|
|
5132
|
+
const annotations = effectiveNamedDecl ? extractNamedTypeAnnotations(effectiveNamedDecl, checker, file, extensionRegistry) : void 0;
|
|
5133
|
+
const metadata = effectiveNamedDecl !== void 0 ? resolveNodeMetadata(
|
|
5152
5134
|
metadataPolicy,
|
|
5153
5135
|
"type",
|
|
5154
5136
|
registryTypeName,
|
|
5155
|
-
|
|
5137
|
+
effectiveNamedDecl,
|
|
5156
5138
|
checker,
|
|
5157
5139
|
extensionRegistry,
|
|
5158
5140
|
{
|
|
5159
5141
|
checker,
|
|
5160
|
-
declaration:
|
|
5142
|
+
declaration: effectiveNamedDecl,
|
|
5161
5143
|
subjectType: type
|
|
5162
5144
|
}
|
|
5163
5145
|
) : void 0;
|
|
@@ -5166,7 +5148,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5166
5148
|
...metadata !== void 0 && { metadata },
|
|
5167
5149
|
type: recordNode,
|
|
5168
5150
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
5169
|
-
provenance: provenanceForDeclaration(
|
|
5151
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
5170
5152
|
};
|
|
5171
5153
|
return {
|
|
5172
5154
|
kind: "reference",
|
|
@@ -5192,7 +5174,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5192
5174
|
if (!declaration) continue;
|
|
5193
5175
|
if (!shouldEmitResolvedObjectProperty(prop, declaration)) continue;
|
|
5194
5176
|
const propType = checker.getTypeOfSymbolAtLocation(prop, declaration);
|
|
5195
|
-
const optional = !!(prop.flags &
|
|
5177
|
+
const optional = !!(prop.flags & ts5.SymbolFlags.Optional);
|
|
5196
5178
|
const propTypeNode = resolveTypeNode(
|
|
5197
5179
|
propType,
|
|
5198
5180
|
checker,
|
|
@@ -5205,7 +5187,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5205
5187
|
collectedDiagnostics
|
|
5206
5188
|
);
|
|
5207
5189
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
5208
|
-
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ?
|
|
5190
|
+
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts5.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
|
|
5209
5191
|
declaration,
|
|
5210
5192
|
checker,
|
|
5211
5193
|
file,
|
|
@@ -5215,7 +5197,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5215
5197
|
type,
|
|
5216
5198
|
metadataPolicy,
|
|
5217
5199
|
extensionRegistry
|
|
5218
|
-
) :
|
|
5200
|
+
) : ts5.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
|
|
5219
5201
|
declaration,
|
|
5220
5202
|
checker,
|
|
5221
5203
|
file,
|
|
@@ -5243,9 +5225,9 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5243
5225
|
visiting.delete(type);
|
|
5244
5226
|
const objectNode = {
|
|
5245
5227
|
kind: "object",
|
|
5246
|
-
properties:
|
|
5228
|
+
properties: effectiveNamedDecl !== void 0 && (ts5.isClassDeclaration(effectiveNamedDecl) || ts5.isInterfaceDeclaration(effectiveNamedDecl) || ts5.isTypeAliasDeclaration(effectiveNamedDecl)) ? applyDiscriminatorToObjectProperties(
|
|
5247
5229
|
properties,
|
|
5248
|
-
|
|
5230
|
+
effectiveNamedDecl,
|
|
5249
5231
|
type,
|
|
5250
5232
|
checker,
|
|
5251
5233
|
file,
|
|
@@ -5255,17 +5237,17 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5255
5237
|
additionalProperties: true
|
|
5256
5238
|
};
|
|
5257
5239
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
5258
|
-
const annotations =
|
|
5259
|
-
const metadata =
|
|
5240
|
+
const annotations = effectiveNamedDecl ? extractNamedTypeAnnotations(effectiveNamedDecl, checker, file, extensionRegistry) : void 0;
|
|
5241
|
+
const metadata = effectiveNamedDecl !== void 0 ? resolveNodeMetadata(
|
|
5260
5242
|
metadataPolicy,
|
|
5261
5243
|
"type",
|
|
5262
5244
|
registryTypeName,
|
|
5263
|
-
|
|
5245
|
+
effectiveNamedDecl,
|
|
5264
5246
|
checker,
|
|
5265
5247
|
extensionRegistry,
|
|
5266
5248
|
{
|
|
5267
5249
|
checker,
|
|
5268
|
-
declaration:
|
|
5250
|
+
declaration: effectiveNamedDecl,
|
|
5269
5251
|
subjectType: type
|
|
5270
5252
|
}
|
|
5271
5253
|
) : void 0;
|
|
@@ -5274,7 +5256,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
5274
5256
|
...metadata !== void 0 && { metadata },
|
|
5275
5257
|
type: objectNode,
|
|
5276
5258
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
5277
|
-
provenance: provenanceForDeclaration(
|
|
5259
|
+
provenance: provenanceForDeclaration(effectiveNamedDecl, file)
|
|
5278
5260
|
};
|
|
5279
5261
|
return {
|
|
5280
5262
|
kind: "reference",
|
|
@@ -5291,12 +5273,12 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
5291
5273
|
for (const symbol of symbols) {
|
|
5292
5274
|
const declarations = symbol.declarations;
|
|
5293
5275
|
if (!declarations) continue;
|
|
5294
|
-
const classDecl = declarations.find(
|
|
5276
|
+
const classDecl = declarations.find(ts5.isClassDeclaration);
|
|
5295
5277
|
if (classDecl) {
|
|
5296
5278
|
const map = /* @__PURE__ */ new Map();
|
|
5297
5279
|
const hostType = checker.getTypeAtLocation(classDecl);
|
|
5298
5280
|
for (const member of classDecl.members) {
|
|
5299
|
-
if (
|
|
5281
|
+
if (ts5.isPropertyDeclaration(member) && ts5.isIdentifier(member.name)) {
|
|
5300
5282
|
const fieldNode = analyzeFieldToIR(
|
|
5301
5283
|
member,
|
|
5302
5284
|
checker,
|
|
@@ -5320,7 +5302,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
5320
5302
|
}
|
|
5321
5303
|
return map;
|
|
5322
5304
|
}
|
|
5323
|
-
const interfaceDecl = declarations.find(
|
|
5305
|
+
const interfaceDecl = declarations.find(ts5.isInterfaceDeclaration);
|
|
5324
5306
|
if (interfaceDecl) {
|
|
5325
5307
|
return buildFieldNodeInfoMap(
|
|
5326
5308
|
interfaceDecl.members,
|
|
@@ -5334,7 +5316,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
5334
5316
|
extensionRegistry
|
|
5335
5317
|
);
|
|
5336
5318
|
}
|
|
5337
|
-
const typeAliasDecl = declarations.find(
|
|
5319
|
+
const typeAliasDecl = declarations.find(ts5.isTypeAliasDeclaration);
|
|
5338
5320
|
const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
|
|
5339
5321
|
if (typeAliasDecl && typeAliasMembers !== null) {
|
|
5340
5322
|
return buildFieldNodeInfoMap(
|
|
@@ -5358,10 +5340,10 @@ function extractArrayElementTypeNode(sourceNode, checker) {
|
|
|
5358
5340
|
return void 0;
|
|
5359
5341
|
}
|
|
5360
5342
|
const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
|
|
5361
|
-
if (
|
|
5343
|
+
if (ts5.isArrayTypeNode(resolvedTypeNode)) {
|
|
5362
5344
|
return resolvedTypeNode.elementType;
|
|
5363
5345
|
}
|
|
5364
|
-
if (
|
|
5346
|
+
if (ts5.isTypeReferenceNode(resolvedTypeNode) && ts5.isIdentifier(resolvedTypeNode.typeName) && resolvedTypeNode.typeName.text === "Array" && resolvedTypeNode.typeArguments?.[0]) {
|
|
5365
5347
|
return resolvedTypeNode.typeArguments[0];
|
|
5366
5348
|
}
|
|
5367
5349
|
return void 0;
|
|
@@ -5372,13 +5354,13 @@ function extractUnionMemberTypeNodes(sourceNode, checker) {
|
|
|
5372
5354
|
return [];
|
|
5373
5355
|
}
|
|
5374
5356
|
const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
|
|
5375
|
-
return
|
|
5357
|
+
return ts5.isUnionTypeNode(resolvedTypeNode) ? [...resolvedTypeNode.types] : [];
|
|
5376
5358
|
}
|
|
5377
5359
|
function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new Set()) {
|
|
5378
|
-
if (
|
|
5360
|
+
if (ts5.isParenthesizedTypeNode(typeNode)) {
|
|
5379
5361
|
return resolveAliasedTypeNode(typeNode.type, checker, visited);
|
|
5380
5362
|
}
|
|
5381
|
-
if (!
|
|
5363
|
+
if (!ts5.isTypeReferenceNode(typeNode) || !ts5.isIdentifier(typeNode.typeName)) {
|
|
5382
5364
|
return typeNode;
|
|
5383
5365
|
}
|
|
5384
5366
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
@@ -5389,15 +5371,15 @@ function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new
|
|
|
5389
5371
|
return resolveAliasedTypeNode(aliasDecl.type, checker, visited);
|
|
5390
5372
|
}
|
|
5391
5373
|
function isNullishTypeNode(typeNode) {
|
|
5392
|
-
if (typeNode.kind ===
|
|
5374
|
+
if (typeNode.kind === ts5.SyntaxKind.NullKeyword || typeNode.kind === ts5.SyntaxKind.UndefinedKeyword) {
|
|
5393
5375
|
return true;
|
|
5394
5376
|
}
|
|
5395
|
-
return
|
|
5377
|
+
return ts5.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts5.SyntaxKind.NullKeyword || typeNode.literal.kind === ts5.SyntaxKind.UndefinedKeyword);
|
|
5396
5378
|
}
|
|
5397
5379
|
function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, metadataPolicy, hostType, diagnostics, extensionRegistry) {
|
|
5398
5380
|
const map = /* @__PURE__ */ new Map();
|
|
5399
5381
|
for (const member of members) {
|
|
5400
|
-
if (
|
|
5382
|
+
if (ts5.isPropertySignature(member)) {
|
|
5401
5383
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
5402
5384
|
member,
|
|
5403
5385
|
checker,
|
|
@@ -5422,7 +5404,7 @@ function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, m
|
|
|
5422
5404
|
return map;
|
|
5423
5405
|
}
|
|
5424
5406
|
function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegistry, depth = 0) {
|
|
5425
|
-
if (!
|
|
5407
|
+
if (!ts5.isTypeReferenceNode(typeNode)) return [];
|
|
5426
5408
|
if (depth >= MAX_ALIAS_CHAIN_DEPTH) {
|
|
5427
5409
|
const aliasName = typeNode.typeName.getText();
|
|
5428
5410
|
throw new Error(
|
|
@@ -5431,7 +5413,7 @@ function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegis
|
|
|
5431
5413
|
}
|
|
5432
5414
|
const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
5433
5415
|
if (!aliasDecl) return [];
|
|
5434
|
-
if (
|
|
5416
|
+
if (ts5.isTypeLiteralNode(aliasDecl.type)) return [];
|
|
5435
5417
|
const aliasFieldType = resolveTypeNode(
|
|
5436
5418
|
checker.getTypeAtLocation(aliasDecl.type),
|
|
5437
5419
|
checker,
|
|
@@ -5475,14 +5457,14 @@ function getNamedTypeName(type) {
|
|
|
5475
5457
|
const symbol = type.getSymbol();
|
|
5476
5458
|
if (symbol?.declarations) {
|
|
5477
5459
|
const decl = symbol.declarations[0];
|
|
5478
|
-
if (decl && (
|
|
5479
|
-
const name =
|
|
5460
|
+
if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
|
|
5461
|
+
const name = ts5.isClassDeclaration(decl) ? decl.name?.text : decl.name.text;
|
|
5480
5462
|
if (name) return name;
|
|
5481
5463
|
}
|
|
5482
5464
|
}
|
|
5483
5465
|
const aliasSymbol = type.aliasSymbol;
|
|
5484
5466
|
if (aliasSymbol?.declarations) {
|
|
5485
|
-
const aliasDecl = aliasSymbol.declarations.find(
|
|
5467
|
+
const aliasDecl = aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
|
|
5486
5468
|
if (aliasDecl) {
|
|
5487
5469
|
return aliasDecl.name.text;
|
|
5488
5470
|
}
|
|
@@ -5493,24 +5475,24 @@ function getNamedTypeDeclaration(type) {
|
|
|
5493
5475
|
const symbol = type.getSymbol();
|
|
5494
5476
|
if (symbol?.declarations) {
|
|
5495
5477
|
const decl = symbol.declarations[0];
|
|
5496
|
-
if (decl && (
|
|
5478
|
+
if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
|
|
5497
5479
|
return decl;
|
|
5498
5480
|
}
|
|
5499
5481
|
}
|
|
5500
5482
|
const aliasSymbol = type.aliasSymbol;
|
|
5501
5483
|
if (aliasSymbol?.declarations) {
|
|
5502
|
-
return aliasSymbol.declarations.find(
|
|
5484
|
+
return aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
|
|
5503
5485
|
}
|
|
5504
5486
|
return void 0;
|
|
5505
5487
|
}
|
|
5506
5488
|
function analyzeMethod(method, checker) {
|
|
5507
|
-
if (!
|
|
5489
|
+
if (!ts5.isIdentifier(method.name)) {
|
|
5508
5490
|
return null;
|
|
5509
5491
|
}
|
|
5510
5492
|
const name = method.name.text;
|
|
5511
5493
|
const parameters = [];
|
|
5512
5494
|
for (const param of method.parameters) {
|
|
5513
|
-
if (
|
|
5495
|
+
if (ts5.isIdentifier(param.name)) {
|
|
5514
5496
|
const paramInfo = analyzeParameter(param, checker);
|
|
5515
5497
|
parameters.push(paramInfo);
|
|
5516
5498
|
}
|
|
@@ -5521,7 +5503,7 @@ function analyzeMethod(method, checker) {
|
|
|
5521
5503
|
return { name, parameters, returnTypeNode, returnType };
|
|
5522
5504
|
}
|
|
5523
5505
|
function analyzeParameter(param, checker) {
|
|
5524
|
-
const name =
|
|
5506
|
+
const name = ts5.isIdentifier(param.name) ? param.name.text : "param";
|
|
5525
5507
|
const typeNode = param.type;
|
|
5526
5508
|
const type = checker.getTypeAtLocation(param);
|
|
5527
5509
|
const formSpecExportName = detectFormSpecReference(typeNode);
|
|
@@ -5530,20 +5512,20 @@ function analyzeParameter(param, checker) {
|
|
|
5530
5512
|
}
|
|
5531
5513
|
function detectFormSpecReference(typeNode) {
|
|
5532
5514
|
if (!typeNode) return null;
|
|
5533
|
-
if (!
|
|
5534
|
-
const typeName =
|
|
5515
|
+
if (!ts5.isTypeReferenceNode(typeNode)) return null;
|
|
5516
|
+
const typeName = ts5.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : ts5.isQualifiedName(typeNode.typeName) ? typeNode.typeName.right.text : null;
|
|
5535
5517
|
if (typeName !== "InferSchema" && typeName !== "InferFormSchema") return null;
|
|
5536
5518
|
const typeArg = typeNode.typeArguments?.[0];
|
|
5537
|
-
if (!typeArg || !
|
|
5538
|
-
if (
|
|
5519
|
+
if (!typeArg || !ts5.isTypeQueryNode(typeArg)) return null;
|
|
5520
|
+
if (ts5.isIdentifier(typeArg.exprName)) {
|
|
5539
5521
|
return typeArg.exprName.text;
|
|
5540
5522
|
}
|
|
5541
|
-
if (
|
|
5523
|
+
if (ts5.isQualifiedName(typeArg.exprName)) {
|
|
5542
5524
|
return typeArg.exprName.right.text;
|
|
5543
5525
|
}
|
|
5544
5526
|
return null;
|
|
5545
5527
|
}
|
|
5546
|
-
var RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
|
|
5528
|
+
var RESOLVING_TYPE_PLACEHOLDER, DEDUPLICATABLE_DIAGNOSTIC_CODES, INHERITABLE_TYPE_ANNOTATION_KINDS, MAX_ALIAS_CHAIN_DEPTH;
|
|
5547
5529
|
var init_class_analyzer = __esm({
|
|
5548
5530
|
"src/analyzer/class-analyzer.ts"() {
|
|
5549
5531
|
"use strict";
|
|
@@ -5558,12 +5540,17 @@ var init_class_analyzer = __esm({
|
|
|
5558
5540
|
properties: [],
|
|
5559
5541
|
additionalProperties: true
|
|
5560
5542
|
};
|
|
5543
|
+
DEDUPLICATABLE_DIAGNOSTIC_CODES = /* @__PURE__ */ new Set([
|
|
5544
|
+
"SYNTHETIC_SETUP_FAILURE",
|
|
5545
|
+
"UNSUPPORTED_CUSTOM_TYPE_OVERRIDE"
|
|
5546
|
+
]);
|
|
5547
|
+
INHERITABLE_TYPE_ANNOTATION_KINDS = /* @__PURE__ */ new Set(["format"]);
|
|
5561
5548
|
MAX_ALIAS_CHAIN_DEPTH = 8;
|
|
5562
5549
|
}
|
|
5563
5550
|
});
|
|
5564
5551
|
|
|
5565
5552
|
// src/analyzer/program.ts
|
|
5566
|
-
import * as
|
|
5553
|
+
import * as ts6 from "typescript";
|
|
5567
5554
|
import * as path from "path";
|
|
5568
5555
|
function createProgramContextFromProgram(program, filePath) {
|
|
5569
5556
|
const absolutePath = path.resolve(filePath);
|
|
@@ -5580,23 +5567,23 @@ function createProgramContextFromProgram(program, filePath) {
|
|
|
5580
5567
|
function createProgramContext(filePath, additionalFiles) {
|
|
5581
5568
|
const absolutePath = path.resolve(filePath);
|
|
5582
5569
|
const fileDir = path.dirname(absolutePath);
|
|
5583
|
-
const configPath =
|
|
5570
|
+
const configPath = ts6.findConfigFile(fileDir, ts6.sys.fileExists.bind(ts6.sys), "tsconfig.json");
|
|
5584
5571
|
let compilerOptions;
|
|
5585
5572
|
let fileNames;
|
|
5586
5573
|
if (configPath) {
|
|
5587
|
-
const configFile =
|
|
5574
|
+
const configFile = ts6.readConfigFile(configPath, ts6.sys.readFile.bind(ts6.sys));
|
|
5588
5575
|
if (configFile.error) {
|
|
5589
5576
|
throw new Error(
|
|
5590
|
-
`Error reading tsconfig.json: ${
|
|
5577
|
+
`Error reading tsconfig.json: ${ts6.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
|
|
5591
5578
|
);
|
|
5592
5579
|
}
|
|
5593
|
-
const parsed =
|
|
5580
|
+
const parsed = ts6.parseJsonConfigFileContent(
|
|
5594
5581
|
configFile.config,
|
|
5595
|
-
|
|
5582
|
+
ts6.sys,
|
|
5596
5583
|
path.dirname(configPath)
|
|
5597
5584
|
);
|
|
5598
5585
|
if (parsed.errors.length > 0) {
|
|
5599
|
-
const errorMessages = parsed.errors.map((e) =>
|
|
5586
|
+
const errorMessages = parsed.errors.map((e) => ts6.flattenDiagnosticMessageText(e.messageText, "\n")).join("\n");
|
|
5600
5587
|
throw new Error(`Error parsing tsconfig.json: ${errorMessages}`);
|
|
5601
5588
|
}
|
|
5602
5589
|
compilerOptions = parsed.options;
|
|
@@ -5604,9 +5591,9 @@ function createProgramContext(filePath, additionalFiles) {
|
|
|
5604
5591
|
fileNames = [.../* @__PURE__ */ new Set([...parsed.fileNames, absolutePath, ...normalizedAdditional])];
|
|
5605
5592
|
} else {
|
|
5606
5593
|
compilerOptions = {
|
|
5607
|
-
target:
|
|
5608
|
-
module:
|
|
5609
|
-
moduleResolution:
|
|
5594
|
+
target: ts6.ScriptTarget.ES2022,
|
|
5595
|
+
module: ts6.ModuleKind.NodeNext,
|
|
5596
|
+
moduleResolution: ts6.ModuleResolutionKind.NodeNext,
|
|
5610
5597
|
strict: true,
|
|
5611
5598
|
skipLibCheck: true,
|
|
5612
5599
|
declaration: true
|
|
@@ -5614,7 +5601,7 @@ function createProgramContext(filePath, additionalFiles) {
|
|
|
5614
5601
|
const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
|
|
5615
5602
|
fileNames = [.../* @__PURE__ */ new Set([absolutePath, ...normalizedAdditional])];
|
|
5616
5603
|
}
|
|
5617
|
-
const program =
|
|
5604
|
+
const program = ts6.createProgram(fileNames, compilerOptions);
|
|
5618
5605
|
const sourceFile = program.getSourceFile(absolutePath);
|
|
5619
5606
|
if (!sourceFile) {
|
|
5620
5607
|
throw new Error(`Could not find source file: ${absolutePath}`);
|
|
@@ -5633,19 +5620,19 @@ function findNodeByName(sourceFile, name, predicate, getName) {
|
|
|
5633
5620
|
result = node;
|
|
5634
5621
|
return;
|
|
5635
5622
|
}
|
|
5636
|
-
|
|
5623
|
+
ts6.forEachChild(node, visit);
|
|
5637
5624
|
}
|
|
5638
5625
|
visit(sourceFile);
|
|
5639
5626
|
return result;
|
|
5640
5627
|
}
|
|
5641
5628
|
function findClassByName(sourceFile, className) {
|
|
5642
|
-
return findNodeByName(sourceFile, className,
|
|
5629
|
+
return findNodeByName(sourceFile, className, ts6.isClassDeclaration, (n) => n.name?.text);
|
|
5643
5630
|
}
|
|
5644
5631
|
function findInterfaceByName(sourceFile, interfaceName) {
|
|
5645
|
-
return findNodeByName(sourceFile, interfaceName,
|
|
5632
|
+
return findNodeByName(sourceFile, interfaceName, ts6.isInterfaceDeclaration, (n) => n.name.text);
|
|
5646
5633
|
}
|
|
5647
5634
|
function findTypeAliasByName(sourceFile, aliasName) {
|
|
5648
|
-
return findNodeByName(sourceFile, aliasName,
|
|
5635
|
+
return findNodeByName(sourceFile, aliasName, ts6.isTypeAliasDeclaration, (n) => n.name.text);
|
|
5649
5636
|
}
|
|
5650
5637
|
function getResolvedObjectRootType(rootType, typeRegistry) {
|
|
5651
5638
|
if (rootType.kind === "object") {
|
|
@@ -5685,22 +5672,22 @@ function createResolvedObjectAliasAnalysis(name, rootType, typeRegistry, rootInf
|
|
|
5685
5672
|
};
|
|
5686
5673
|
}
|
|
5687
5674
|
function containsTypeReferenceInObjectLikeAlias(typeNode) {
|
|
5688
|
-
if (
|
|
5675
|
+
if (ts6.isParenthesizedTypeNode(typeNode)) {
|
|
5689
5676
|
return containsTypeReferenceInObjectLikeAlias(typeNode.type);
|
|
5690
5677
|
}
|
|
5691
|
-
if (
|
|
5678
|
+
if (ts6.isTypeReferenceNode(typeNode)) {
|
|
5692
5679
|
return true;
|
|
5693
5680
|
}
|
|
5694
|
-
return
|
|
5681
|
+
return ts6.isIntersectionTypeNode(typeNode) && typeNode.types.some((member) => containsTypeReferenceInObjectLikeAlias(member));
|
|
5695
5682
|
}
|
|
5696
5683
|
function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
|
|
5697
|
-
if (
|
|
5684
|
+
if (ts6.isParenthesizedTypeNode(typeNode)) {
|
|
5698
5685
|
return collectFallbackAliasMemberPropertyNames(typeNode.type, checker);
|
|
5699
5686
|
}
|
|
5700
|
-
if (
|
|
5687
|
+
if (ts6.isTypeLiteralNode(typeNode)) {
|
|
5701
5688
|
const propertyNames = [];
|
|
5702
5689
|
for (const member of typeNode.members) {
|
|
5703
|
-
if (!
|
|
5690
|
+
if (!ts6.isPropertySignature(member)) {
|
|
5704
5691
|
continue;
|
|
5705
5692
|
}
|
|
5706
5693
|
const propertyName = getAnalyzableObjectLikePropertyName(member.name);
|
|
@@ -5710,13 +5697,13 @@ function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
|
|
|
5710
5697
|
}
|
|
5711
5698
|
return propertyNames;
|
|
5712
5699
|
}
|
|
5713
|
-
if (
|
|
5700
|
+
if (ts6.isTypeReferenceNode(typeNode)) {
|
|
5714
5701
|
return checker.getTypeFromTypeNode(typeNode).getProperties().map((property) => property.getName());
|
|
5715
5702
|
}
|
|
5716
5703
|
return null;
|
|
5717
5704
|
}
|
|
5718
5705
|
function findFallbackAliasDuplicatePropertyNames(typeNode, checker) {
|
|
5719
|
-
if (!
|
|
5706
|
+
if (!ts6.isIntersectionTypeNode(typeNode)) {
|
|
5720
5707
|
return [];
|
|
5721
5708
|
}
|
|
5722
5709
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -5923,7 +5910,7 @@ var init_program = __esm({
|
|
|
5923
5910
|
});
|
|
5924
5911
|
|
|
5925
5912
|
// src/extensions/symbol-registry.ts
|
|
5926
|
-
import * as
|
|
5913
|
+
import * as ts7 from "typescript";
|
|
5927
5914
|
import * as path2 from "path";
|
|
5928
5915
|
function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistry) {
|
|
5929
5916
|
const symbolMap = /* @__PURE__ */ new Map();
|
|
@@ -5933,10 +5920,10 @@ function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistr
|
|
|
5933
5920
|
return symbolMap;
|
|
5934
5921
|
}
|
|
5935
5922
|
function visit(node) {
|
|
5936
|
-
if (
|
|
5923
|
+
if (ts7.isCallExpression(node) && isDefineCustomTypeCall(node, checker)) {
|
|
5937
5924
|
processDefineCustomTypeCall(node);
|
|
5938
5925
|
}
|
|
5939
|
-
|
|
5926
|
+
ts7.forEachChild(node, visit);
|
|
5940
5927
|
}
|
|
5941
5928
|
function processDefineCustomTypeCall(call) {
|
|
5942
5929
|
const typeArgNode = call.typeArguments?.[0];
|
|
@@ -5973,7 +5960,7 @@ function isDefineCustomTypeCall(node, checker) {
|
|
|
5973
5960
|
if (node.typeArguments === void 0 || node.typeArguments.length === 0) return false;
|
|
5974
5961
|
const callSymbol = checker.getSymbolAtLocation(node.expression);
|
|
5975
5962
|
if (callSymbol !== void 0) {
|
|
5976
|
-
const resolved = callSymbol.flags &
|
|
5963
|
+
const resolved = callSymbol.flags & ts7.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
|
|
5977
5964
|
const decl = resolved.declarations?.[0];
|
|
5978
5965
|
if (decl !== void 0) {
|
|
5979
5966
|
const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
|
|
@@ -5981,24 +5968,24 @@ function isDefineCustomTypeCall(node, checker) {
|
|
|
5981
5968
|
(sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
|
|
5982
5969
|
}
|
|
5983
5970
|
}
|
|
5984
|
-
return
|
|
5971
|
+
return ts7.isIdentifier(node.expression) && node.expression.text === "defineCustomType";
|
|
5985
5972
|
}
|
|
5986
5973
|
function extractTypeNameFromCallArg(call) {
|
|
5987
5974
|
const arg = call.arguments[0];
|
|
5988
|
-
if (arg === void 0 || !
|
|
5975
|
+
if (arg === void 0 || !ts7.isObjectLiteralExpression(arg)) {
|
|
5989
5976
|
return null;
|
|
5990
5977
|
}
|
|
5991
5978
|
const typeNameProp = arg.properties.find(
|
|
5992
|
-
(p) =>
|
|
5979
|
+
(p) => ts7.isPropertyAssignment(p) && ts7.isIdentifier(p.name) && p.name.text === "typeName"
|
|
5993
5980
|
);
|
|
5994
|
-
if (typeNameProp === void 0 || !
|
|
5981
|
+
if (typeNameProp === void 0 || !ts7.isStringLiteral(typeNameProp.initializer)) {
|
|
5995
5982
|
return null;
|
|
5996
5983
|
}
|
|
5997
5984
|
return typeNameProp.initializer.text;
|
|
5998
5985
|
}
|
|
5999
5986
|
function extractEnclosingExtensionId(call, checker) {
|
|
6000
|
-
for (let node = call.parent; !
|
|
6001
|
-
if (
|
|
5987
|
+
for (let node = call.parent; !ts7.isSourceFile(node); node = node.parent) {
|
|
5988
|
+
if (ts7.isCallExpression(node) && isDefineExtensionCall(node, checker)) {
|
|
6002
5989
|
return extractExtensionIdFromCallArg(node);
|
|
6003
5990
|
}
|
|
6004
5991
|
}
|
|
@@ -6007,24 +5994,24 @@ function extractEnclosingExtensionId(call, checker) {
|
|
|
6007
5994
|
function isDefineExtensionCall(node, checker) {
|
|
6008
5995
|
const callSymbol = checker.getSymbolAtLocation(node.expression);
|
|
6009
5996
|
if (callSymbol !== void 0) {
|
|
6010
|
-
const resolved = callSymbol.flags &
|
|
5997
|
+
const resolved = callSymbol.flags & ts7.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
|
|
6011
5998
|
const decl = resolved.declarations?.[0];
|
|
6012
5999
|
if (decl !== void 0) {
|
|
6013
6000
|
const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
|
|
6014
6001
|
return resolved.name === "defineExtension" && (sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
|
|
6015
6002
|
}
|
|
6016
6003
|
}
|
|
6017
|
-
return
|
|
6004
|
+
return ts7.isIdentifier(node.expression) && node.expression.text === "defineExtension";
|
|
6018
6005
|
}
|
|
6019
6006
|
function extractExtensionIdFromCallArg(call) {
|
|
6020
6007
|
const arg = call.arguments[0];
|
|
6021
|
-
if (arg === void 0 || !
|
|
6008
|
+
if (arg === void 0 || !ts7.isObjectLiteralExpression(arg)) {
|
|
6022
6009
|
return null;
|
|
6023
6010
|
}
|
|
6024
6011
|
const prop = arg.properties.find(
|
|
6025
|
-
(p) =>
|
|
6012
|
+
(p) => ts7.isPropertyAssignment(p) && ts7.isIdentifier(p.name) && p.name.text === "extensionId"
|
|
6026
6013
|
);
|
|
6027
|
-
if (prop === void 0 || !
|
|
6014
|
+
if (prop === void 0 || !ts7.isStringLiteral(prop.initializer)) {
|
|
6028
6015
|
return null;
|
|
6029
6016
|
}
|
|
6030
6017
|
return prop.initializer.text;
|
|
@@ -6136,7 +6123,7 @@ var init_validate = __esm({
|
|
|
6136
6123
|
});
|
|
6137
6124
|
|
|
6138
6125
|
// src/generators/class-schema.ts
|
|
6139
|
-
import * as
|
|
6126
|
+
import * as ts8 from "typescript";
|
|
6140
6127
|
function generateClassSchemas(analysis, source, options) {
|
|
6141
6128
|
const result = generateClassSchemasDetailed(analysis, source, options);
|
|
6142
6129
|
if (!result.ok || result.jsonSchema === void 0 || result.uiSchema === void 0) {
|
|
@@ -6306,7 +6293,7 @@ function generateSchemasBatch(options) {
|
|
|
6306
6293
|
return options.targets.map((target) => {
|
|
6307
6294
|
let ctx;
|
|
6308
6295
|
try {
|
|
6309
|
-
const cacheKey =
|
|
6296
|
+
const cacheKey = ts8.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
|
|
6310
6297
|
const cachedContext = contextCache.get(cacheKey);
|
|
6311
6298
|
if (cachedContext === void 0) {
|
|
6312
6299
|
const additionalFiles = options.configPath !== void 0 ? [options.configPath] : void 0;
|
|
@@ -6365,7 +6352,7 @@ function isMutableRegistry(reg) {
|
|
|
6365
6352
|
}
|
|
6366
6353
|
function resolveStaticOptions(options) {
|
|
6367
6354
|
const legacyRegistry = options.extensionRegistry;
|
|
6368
|
-
const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6355
|
+
const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 && options.config.extensions.length > 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6369
6356
|
return {
|
|
6370
6357
|
extensionRegistry: legacyRegistry ?? configRegistry,
|
|
6371
6358
|
// eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
|
|
@@ -6377,7 +6364,7 @@ function resolveStaticOptions(options) {
|
|
|
6377
6364
|
};
|
|
6378
6365
|
}
|
|
6379
6366
|
function resolveOptions(options) {
|
|
6380
|
-
const configRegistry = options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6367
|
+
const configRegistry = options.config?.extensions !== void 0 && options.config.extensions.length > 0 ? createExtensionRegistry(options.config.extensions) : void 0;
|
|
6381
6368
|
const legacyRegistry = options.extensionRegistry;
|
|
6382
6369
|
return {
|
|
6383
6370
|
// When the caller provides the deprecated extensionRegistry field directly,
|
|
@@ -6475,7 +6462,7 @@ var init_class_schema = __esm({
|
|
|
6475
6462
|
});
|
|
6476
6463
|
|
|
6477
6464
|
// src/static-build.ts
|
|
6478
|
-
import * as
|
|
6465
|
+
import * as ts9 from "typescript";
|
|
6479
6466
|
function toStaticBuildContext(context) {
|
|
6480
6467
|
return context;
|
|
6481
6468
|
}
|
|
@@ -6490,7 +6477,7 @@ function getModuleSymbol(context) {
|
|
|
6490
6477
|
return context.checker.getSymbolAtLocation(context.sourceFile) ?? sourceFileWithSymbol.symbol;
|
|
6491
6478
|
}
|
|
6492
6479
|
function isSchemaSourceDeclaration(declaration) {
|
|
6493
|
-
return
|
|
6480
|
+
return ts9.isClassDeclaration(declaration) || ts9.isInterfaceDeclaration(declaration) || ts9.isTypeAliasDeclaration(declaration);
|
|
6494
6481
|
}
|
|
6495
6482
|
function resolveModuleExport(context, exportName = "default") {
|
|
6496
6483
|
const moduleSymbol = getModuleSymbol(context);
|
|
@@ -6501,7 +6488,7 @@ function resolveModuleExport(context, exportName = "default") {
|
|
|
6501
6488
|
if (exportSymbol === null) {
|
|
6502
6489
|
return null;
|
|
6503
6490
|
}
|
|
6504
|
-
return exportSymbol.flags &
|
|
6491
|
+
return exportSymbol.flags & ts9.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
|
|
6505
6492
|
}
|
|
6506
6493
|
function resolveModuleExportDeclaration(context, exportName = "default") {
|
|
6507
6494
|
return resolveModuleExport(context, exportName)?.declarations?.find(isSchemaSourceDeclaration) ?? null;
|
|
@@ -6514,7 +6501,7 @@ var init_static_build = __esm({
|
|
|
6514
6501
|
});
|
|
6515
6502
|
|
|
6516
6503
|
// src/generators/discovered-schema.ts
|
|
6517
|
-
import * as
|
|
6504
|
+
import * as ts10 from "typescript";
|
|
6518
6505
|
import { analyzeMetadataForNodeWithChecker as analyzeMetadataForNodeWithChecker2 } from "@formspec/analysis/internal";
|
|
6519
6506
|
import { IR_VERSION as IR_VERSION3 } from "@formspec/core/internals";
|
|
6520
6507
|
function toDiscoveredTypeSchemas(result, resolvedMetadata) {
|
|
@@ -6524,17 +6511,17 @@ function toDiscoveredTypeSchemas(result, resolvedMetadata) {
|
|
|
6524
6511
|
};
|
|
6525
6512
|
}
|
|
6526
6513
|
function isNamedTypeDeclaration(declaration) {
|
|
6527
|
-
return
|
|
6514
|
+
return ts10.isClassDeclaration(declaration) || ts10.isInterfaceDeclaration(declaration) || ts10.isTypeAliasDeclaration(declaration);
|
|
6528
6515
|
}
|
|
6529
6516
|
function hasConcreteTypeArguments(type, checker) {
|
|
6530
6517
|
if ("aliasTypeArguments" in type && Array.isArray(type.aliasTypeArguments) && type.aliasTypeArguments.length > 0) {
|
|
6531
6518
|
return true;
|
|
6532
6519
|
}
|
|
6533
|
-
if ((type.flags &
|
|
6520
|
+
if ((type.flags & ts10.TypeFlags.Object) === 0) {
|
|
6534
6521
|
return false;
|
|
6535
6522
|
}
|
|
6536
6523
|
const objectType = type;
|
|
6537
|
-
if ((objectType.objectFlags &
|
|
6524
|
+
if ((objectType.objectFlags & ts10.ObjectFlags.Reference) === 0) {
|
|
6538
6525
|
return false;
|
|
6539
6526
|
}
|
|
6540
6527
|
return checker.getTypeArguments(objectType).length > 0;
|
|
@@ -6547,13 +6534,13 @@ function getNamedTypeDeclaration2(type) {
|
|
|
6547
6534
|
return declaration;
|
|
6548
6535
|
}
|
|
6549
6536
|
}
|
|
6550
|
-
const aliasDeclaration = type.aliasSymbol?.declarations?.find(
|
|
6537
|
+
const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts10.isTypeAliasDeclaration);
|
|
6551
6538
|
return aliasDeclaration;
|
|
6552
6539
|
}
|
|
6553
6540
|
function getFallbackName(sourceNode, fallback = "AnonymousType") {
|
|
6554
6541
|
if (sourceNode !== void 0 && "name" in sourceNode) {
|
|
6555
6542
|
const namedNode = sourceNode;
|
|
6556
|
-
if (namedNode.name !== void 0 &&
|
|
6543
|
+
if (namedNode.name !== void 0 && ts10.isIdentifier(namedNode.name)) {
|
|
6557
6544
|
return namedNode.name.text;
|
|
6558
6545
|
}
|
|
6559
6546
|
}
|
|
@@ -6775,7 +6762,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
|
|
|
6775
6762
|
function generateSchemasFromDeclaration(options) {
|
|
6776
6763
|
const filePath = options.declaration.getSourceFile().fileName;
|
|
6777
6764
|
const resolved = resolveStaticOptions(options);
|
|
6778
|
-
if (
|
|
6765
|
+
if (ts10.isClassDeclaration(options.declaration)) {
|
|
6779
6766
|
return generateSchemasFromAnalysis(
|
|
6780
6767
|
analyzeClassToIR(
|
|
6781
6768
|
options.declaration,
|
|
@@ -6789,7 +6776,7 @@ function generateSchemasFromDeclaration(options) {
|
|
|
6789
6776
|
resolved
|
|
6790
6777
|
);
|
|
6791
6778
|
}
|
|
6792
|
-
if (
|
|
6779
|
+
if (ts10.isInterfaceDeclaration(options.declaration)) {
|
|
6793
6780
|
return generateSchemasFromAnalysis(
|
|
6794
6781
|
analyzeInterfaceToIR(
|
|
6795
6782
|
options.declaration,
|
|
@@ -6803,7 +6790,7 @@ function generateSchemasFromDeclaration(options) {
|
|
|
6803
6790
|
resolved
|
|
6804
6791
|
);
|
|
6805
6792
|
}
|
|
6806
|
-
if (
|
|
6793
|
+
if (ts10.isTypeAliasDeclaration(options.declaration)) {
|
|
6807
6794
|
const analyzedAlias = analyzeTypeAliasToIR(
|
|
6808
6795
|
options.declaration,
|
|
6809
6796
|
options.context.checker,
|
|
@@ -6862,7 +6849,7 @@ function generateSchemasFromReturnType(options) {
|
|
|
6862
6849
|
const returnType = signature !== void 0 ? options.context.checker.getReturnTypeOfSignature(signature) : options.context.checker.getTypeAtLocation(options.declaration);
|
|
6863
6850
|
const type = unwrapPromiseType(options.context.checker, returnType);
|
|
6864
6851
|
const sourceNode = type !== returnType ? unwrapPromiseTypeNode(options.declaration.type) ?? options.declaration.type ?? options.declaration : options.declaration.type ?? options.declaration;
|
|
6865
|
-
const fallbackName = options.declaration.name !== void 0 &&
|
|
6852
|
+
const fallbackName = options.declaration.name !== void 0 && ts10.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
|
|
6866
6853
|
return generateSchemasFromResolvedType({
|
|
6867
6854
|
...options,
|
|
6868
6855
|
type,
|
|
@@ -6909,14 +6896,14 @@ function unwrapPromiseTypeNode(typeNode) {
|
|
|
6909
6896
|
if (typeNode === void 0) {
|
|
6910
6897
|
return void 0;
|
|
6911
6898
|
}
|
|
6912
|
-
if (
|
|
6899
|
+
if (ts10.isParenthesizedTypeNode(typeNode)) {
|
|
6913
6900
|
const unwrapped = unwrapPromiseTypeNode(typeNode.type);
|
|
6914
6901
|
return unwrapped ?? typeNode;
|
|
6915
6902
|
}
|
|
6916
6903
|
return isPromiseTypeReferenceNode(typeNode) ? typeNode.typeArguments[0] : typeNode;
|
|
6917
6904
|
}
|
|
6918
6905
|
function isPromiseTypeReferenceNode(typeNode) {
|
|
6919
|
-
return
|
|
6906
|
+
return ts10.isTypeReferenceNode(typeNode) && ts10.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
|
|
6920
6907
|
}
|
|
6921
6908
|
var init_discovered_schema = __esm({
|
|
6922
6909
|
"src/generators/discovered-schema.ts"() {
|